package com.lancoo.ccas53.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lancoo.ccas53.arrangecourse.common.BinaryUtil;
import com.lancoo.ccas53.entity.*;
import com.lancoo.ccas53.exception.BizException;
import com.lancoo.ccas53.mapper.*;
import com.lancoo.ccas53.pojo.common.PageInfo;
import com.lancoo.ccas53.pojo.constant.GlobalConstant;
import com.lancoo.ccas53.pojo.dto.*;
import com.lancoo.ccas53.pojo.excel.ErrorExcelVo;
import com.lancoo.ccas53.pojo.excel.ExcelSelfTeachingDto;
import com.lancoo.ccas53.pojo.response.basicPlatform.BaseCourse;
import com.lancoo.ccas53.pojo.vo.WeekDateVo;
import com.lancoo.ccas53.service.*;
import com.lancoo.ccas53.util.MyExcelUtils;
import com.lancoo.ccas53.util.PagingUtil;
import com.lancoo.ccas53.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 选课课程 服务实现类
 * </p>
 *
 * @author quin.song
 * @since 2024-05-20
 */
@Service
@Slf4j
public class CssSelectCourseServiceImpl extends ServiceImpl<CssSelectCourseMapper, CssSelectCourse> implements CssSelectCourseService {


    @Resource
    private RedissonClient redissonClient;

    @Resource
    private ScheduleMapper scheduleMapper;
    @Resource
    private CssTaskInfoService cssTaskInfoService;
    @Resource
    private CourseService courseService;
    @Resource
    private CssTaskRoundService cssTaskRoundService;
    @Resource
    private CssRoundCourseService CssRoundCourseService;
    @Resource
    private CssStudentRangeService cssStudentRangeService;
    @Resource
    private StudentService studentService;
    @Resource
    private CssPreSelectStudentService cssPreSelectStudentService;
    @Resource
    private CollegeService collegeService;
    @Resource
    private TeachingClassService teachingClassService;
    @Resource
    private MajorGradeService majorGradeService;
    @Resource
    private PlanTeachingService planTeachingService;
    @Resource
    private PlanTeachingCourseService planTeachingCourseService;
    @Resource
    private TeachingClassStudentService teachingClassStudentService;
    @Resource
    private TeacherService teacherService;
    @Resource
    private CampusService campusService;
    @Resource
    private TeachingClassMapper teachingClassMapper;
    @Resource
    private TeachingClassTeacherService teachingClassTeacherService;
    @Resource
    private TeachingClassWeekService teachingClassWeekService;
    @Resource
    private CourseSelectionService courseSelectionService;
    @Resource
    private DeleteClassService deleteClassService;
    @Resource
    private CssPreSelectStudentMapper cssPreSelectStudentMapper;
    @Resource
    private TeacherMapper teacherMapper;
    @Resource
    private StudentRetakeService studentRetakeService;
    @Resource
    private TaskInfoService taskInfoService;
    @Resource
    @Lazy
    private YunBasicService yunBasicService;
    @Resource
    private TeachingClassWeekMapper teachingClassWeekMapper;
    @Resource
    private CourseWeekService courseWeekService;
    @Resource
    private CssRoundCourseService cssRoundCourseService;
    @Resource
    private PlanTeachingStudentService planTeachingStudentService;
    @Resource
    @Lazy
    private YunBasicServiceImpl yunBasicServiceImpl;
    @Resource
    private AssessmentMethodService assessmentMethodService;
    @Resource
    private ScheduleService scheduleService;

    @Resource
    private ScheduleSelectService scheduleSelectService;
    @Resource
    private CssSelectCourseService cssSelectCourseService;
    @Resource
    private StudentServiceImpl studentServiceImpl;
    @Resource
    private RedisUtil redisUtil;


    @Override
    public CssTaskInfo getCssTask(Integer type, Integer taskId) {
        CssTaskInfo result = new CssTaskInfo();
        List<CssTaskInfo> taskInfos = cssTaskInfoService.lambdaQuery()
                .eq(CssTaskInfo::getTaskId, taskId)
                .eq(CssTaskInfo::getType, type)
                .list();
        if (CollUtil.isNotEmpty(taskInfos)) {
            result = taskInfos.get(0);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CssTaskInfo setCssTask(CssTaskInfo param, Integer taskId) {
        //先删除
        cssTaskInfoService.lambdaUpdate()
                .eq(CssTaskInfo::getTaskId, taskId)
                .eq(CssTaskInfo::getType, param.getType())
                .remove();
        //新增
        CssTaskInfo model = new CssTaskInfo();
        BeanUtils.copyProperties(param, model);
        model.setCreatedTime(new Date());
        cssTaskInfoService.saveOrUpdate(model);

        //修改majorGrade表
        if (param.getType() == 1) {
            majorGradeService.lambdaUpdate()
                    .eq(MajorGrade::getTaskId, taskId)
                    .set(MajorGrade::getPreCourseLimit, param.getCourseLimit())
                    .set(MajorGrade::getPreCreditLimit, param.getCreditLimit())
                    .update();
            studentService.lambdaUpdate()
                    .eq(Student::getTaskId, taskId)
                    .set(Student::getPreCourseLimit, param.getCourseLimit())
                    .set(Student::getPreCreditLimit, param.getCreditLimit())
                    .update();

        } else if (param.getType() == 2) {
            majorGradeService.lambdaUpdate()
                    .eq(MajorGrade::getTaskId, taskId)
                    .set(MajorGrade::getCourseLimit, param.getCourseLimit())
                    .set(MajorGrade::getCreditLimit, param.getCreditLimit())
                    .update();
            studentService.lambdaUpdate()
                    .eq(Student::getTaskId, taskId)
                    .set(Student::getCourseLimit, param.getCourseLimit())
                    .set(Student::getCreditLimit, param.getCreditLimit())
                    .update();
        }
        return model;
    }

    @Override
    public List<SelectCourseListDto> getSelectCourseList(Integer type, Integer dataRange, String baseCollegeId, String courseTypeId, Integer courseNature, String keyword, Integer sexLimit, Integer flag, Integer taskId) {
        List<SelectCourseListDto> selectResult = new ArrayList<>();
        List<SelectCourseListDto> unSelectResult = new ArrayList<>();
        List<CssSelectCourse> selectCourses = cssSelectCourseService.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId)
                .eq(CssSelectCourse::getIsEnable, 1)
                .eq(ObjUtil.isNotEmpty(type) && type.equals(1), CssSelectCourse::getType, type)
                .eq(ObjUtil.isNotEmpty(sexLimit), CssSelectCourse::getSexLimit, sexLimit).list();

        List<Course> courseList = courseService.lambdaQuery().eq(StringUtils.isNotBlank(baseCollegeId), Course::getBaseCollegeId, baseCollegeId)
                .eq(StringUtils.isNotBlank(courseTypeId), Course::getCourseTypeId, courseTypeId)
                .eq(ObjUtil.isNotEmpty(courseNature), Course::getCourseNature, courseNature)
                .like(StringUtils.isNotBlank(keyword), Course::getCourseName, keyword)
                .eq(Course::getTaskId, taskId)
                .eq(Course::getFlag, 1).list();

        //因为本系统可以选择去无条件同步基础平台课程库中所有课程，所以不能直接拿所有的课程遍历
        //同步培养方案时，该培养方案下的课程，只有本学期开的课程会存入中间表PlanTeachingCourse，从中间表获取到本学期开课的课程
        List<PlanTeachingCourse> planTeachingCourses = planTeachingCourseService.lambdaQuery().eq(PlanTeachingCourse::getTaskId, taskId).list();
        List<String> baseCourseIds = planTeachingCourses.stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toList());
        courseList = courseList.stream().filter(a -> baseCourseIds.contains(a.getBaseCourseId())).collect(Collectors.toList());

        if (!courseList.isEmpty()) {
            for (CssSelectCourse item : selectCourses
            ) {
                SelectCourseListDto view = new SelectCourseListDto();
                Optional<Course> course = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                if (course.isPresent()) {
                    BeanUtils.copyProperties(item, view);
                    BeanUtils.copyProperties(course.get(), view);
                    selectResult.add(view);
                }
            }
            List<Long> selectIds = selectResult.stream().map(SelectCourseListDto::getCourseId).collect(Collectors.toList());
            courseList = courseList.stream().filter(a -> !selectIds.contains(a.getCourseId())).collect(Collectors.toList());
            for (Course item : courseList
            ) {
                SelectCourseListDto view = new SelectCourseListDto();
                BeanUtils.copyProperties(item, view);
                unSelectResult.add(view);
            }
        }

        if (dataRange != null && dataRange == 1) {
            //1已设置
            selectResult = selectResult.stream().filter(a -> a.getOperationStatus() == 2).collect(Collectors.toList());
        } else if (dataRange != null && dataRange == 2) {
            //2未设置
            selectResult = selectResult.stream().filter(a -> a.getOperationStatus() == 1).collect(Collectors.toList());
        }
        return flag == 0 ? unSelectResult : selectResult;
    }

    @Override
    public List<CssSelectCourse> addSelectCourse(List<CssSelectCourse> list, Integer type, Integer taskId) {
        //先删除
        this.lambdaUpdate()
                .eq(CssSelectCourse::getTaskId, taskId)
                .remove();
        //保存
        List<CssSelectCourse> result = new ArrayList<>();
        for (CssSelectCourse param : list
        ) {
            CssSelectCourse model = new CssSelectCourse();
            BeanUtils.copyProperties(param, model);
            save(model);
            result.add(model);
        }
        List<Course> courseList = courseService.lambdaQuery()
                .eq(Course::getTaskId, taskId)
                .list();
        for (CssSelectCourse item : list) {
            if (type == 1) {
                Optional<Course> optional = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                if (optional.isPresent()) {
                    Course course = optional.get();
                    if (course.getIsSelect() == 2) {
                        course.setIsSelect(3);
                    } else {
                        course.setIsSelect(1);
                    }
                    courseService.updateById(course);
                }
            } else if (type == 2) {
                Optional<Course> optional = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                if (optional.isPresent()) {
                    Course course = optional.get();
                    if (course.getIsSelect() == 1) {
                        course.setIsSelect(3);
                    } else {
                        course.setIsSelect(2);
                    }
                    courseService.updateById(course);
                }
            }
        }
        return result;
    }

    @Override
    public String setCourseLimit(List<Integer> idList, Optional<Integer> sexLimit, Optional<Integer> classNum, Optional<Integer> operationStatus, Optional<Integer> isEnable, Optional<String> description, Integer taskId) {
        for (Integer id : idList
        ) {
            CssSelectCourse model = getById(id);
            if (model != null) {
                sexLimit.ifPresent(model::setSexLimit);
                classNum.ifPresent(model::setClassNum);
                operationStatus.ifPresent(model::setOperationStatus);
                isEnable.ifPresent(model::setIsEnable);
                description.ifPresent(model::setDescription);
                model.setOperationStatus(2);
                updateById(model);
            }
        }
        return "成功";
    }

    @Override
    public List<RoundListDto> getRoundList(Optional<Integer> type, Integer taskId) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<RoundListDto> result = new ArrayList<>();
        QueryWrapper<CssTaskRound> queryWrapper = new QueryWrapper<>();
        type.ifPresent(a -> queryWrapper.eq("type", a));
        queryWrapper.eq("task_id", taskId);
        List<CssTaskRound> rounds = cssTaskRoundService.list(queryWrapper);
        QueryWrapper queryWrapper1 = new QueryWrapper();
        queryWrapper1.eq("task_id", taskId);
        List<CssRoundCourse> roundCourses = CssRoundCourseService.list(queryWrapper1);
        List<CssStudentRange> studentRanges = cssStudentRangeService.list(queryWrapper1);
        List<Student> studentList = studentService.list(queryWrapper1);
        studentList = studentList.stream().filter(a -> a.getBaseStudentId() != null && a.getGradeId() != null && a.getMajorId() != null).collect(Collectors.toList());
        List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).eq(TeachingClass::getTeachingClassType, 1).list();

        List<TeachingClassStudent> teachingClassStudents = new ArrayList<>();
        if (CollUtil.isNotEmpty(teachingClasses)) {
            List<Long> teachingClassIds = teachingClasses.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            teachingClassStudents = teachingClassStudentService.lambdaQuery()
                    .in(TeachingClassStudent::getTeachingClassId, teachingClassIds)
                    .eq(TeachingClassStudent::getFlag, 1)
                    .list();
        }

        List<StudentRetake> studentRetakes = studentRetakeService.lambdaQuery()
                .eq(StudentRetake::getTaskId, taskId).list();
        List<CourseSelection> courseSelectionList = courseSelectionService.lambdaQuery().eq(CourseSelection::getTaskId, taskId).list();

        for (CssTaskRound item : rounds) {
            if (item.getSelectType().equals(4)) {
                //自学选课
                RoundListDto view = new RoundListDto();
                BeanUtils.copyProperties(item, view);
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String beginTime = format.format(item.getBeginTime());
                String endTime = format.format(item.getEndTime());
                view.setBeginTime(beginTime);
                view.setEndTime(endTime);
                //通过id在css_student_range表中找到符合条件的选课院系和学生范围
                List<CourseSelection> courseSelections = courseSelectionList.stream().filter(a -> a.getRoundId().equals(item.getId())).collect(Collectors.toList());
                int studentNum = 0;
                for (CourseSelection courseSelection : courseSelections) {
                    List<Student> tempStudents = studentList.stream().filter(o -> o.getBaseCollegeId().equals(courseSelection.getBaseCollegeId())
                            && o.getGradeId().equals(courseSelection.getGradeId())).collect(Collectors.toList());
                    studentNum += tempStudents.size();
                }
                view.setStudentNum(studentNum);

                List<StudentRangeDto> studentRangeList = new ArrayList<>();
                List<String> collegeNameList = courseSelections.stream().map(CourseSelection::getBaseCollegeName).distinct().collect(Collectors.toList());
                for (String name : collegeNameList) {
                    StudentRangeDto rangeDto = new StudentRangeDto();
                    rangeDto.setId(courseSelections.stream().filter(a -> a.getBaseCollegeName().equals(name)).findFirst().get().getBaseCollegeId());
                    rangeDto.setName(name);
                    List<String> gradeNameList = courseSelections.stream().filter(a -> a.getBaseCollegeName().equals(name)).map(CourseSelection::getGradeName).distinct().collect(Collectors.toList());
                    List<StudentRangeChildDto> list = new ArrayList<>();
                    for (String gradeName : gradeNameList) {
                        StudentRangeChildDto rangeChildDto = new StudentRangeChildDto();
                        rangeChildDto.setName(gradeName);
                        rangeChildDto.setId(courseSelections.stream().filter(a -> a.getGradeName().equals(gradeName)).findFirst().get().getGradeId());
                        List<Student> students = studentList.stream().filter(a -> a.getGradeName().equals(gradeName) && a.getCollegeName().equals(name)).collect(Collectors.toList());
                        rangeChildDto.setStudentCount(students.size());
                        list.add(rangeChildDto);
                    }
                    rangeDto.setList(list);
                    studentRangeList.add(rangeDto);
                }
                view.setStudentRangeList(studentRangeList);
                result.add(view);
            } else if (item.getSelectType().equals(3)) {
                //重修选课
                RoundListDto view = new RoundListDto();
                view.setTaskId(taskId);
                view.setId(item.getId());
                view.setType(2);
                view.setSelectType(3);
                view.setSelectAuthority(item.getSelectAuthority());
                view.setRound(item.getRound());
                view.setRoundName(item.getRoundName());
                view.setCrossMajor(item.getCrossMajor());
                view.setBeginTime(dateFormat.format(item.getBeginTime()));
                view.setEndTime(dateFormat.format(item.getEndTime()));
                view.setIsEnable(item.getIsEnable());
                view.setTotalStudent(studentRetakes.size());
                if (CollUtil.isNotEmpty(studentRetakes)) {
                    List<String> baseStudentIds = studentRetakes.stream().map(StudentRetake::getBaseStudentId).collect(Collectors.toList());
                    List<Student> students = studentList.stream().filter(p -> baseStudentIds.contains(p.getBaseStudentId())).collect(Collectors.toList());

                    if (CollUtil.isNotEmpty(students)) {
                        List<Long> studentIds = students.stream().map(Student::getStudentId).collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(teachingClassStudents)) {
                            List<Long> collect = teachingClassStudents.stream().map(TeachingClassStudent::getStudentId).distinct().collect(Collectors.toList());

                            List<Long> studentNums = studentIds.stream().filter(collect::contains).collect(Collectors.toList());
                            view.setStudentNum(studentNums.size());
                        }
                    }
                }
                result.add(view);
            } else {
                //正选选课
                Integer totalStudent = 0;
                List<StudentRangeDto> studentRangeList = new ArrayList<>();
                RoundListDto view = new RoundListDto();
                BeanUtils.copyProperties(item, view);
                List<CssRoundCourse> roundCourse = roundCourses.stream().filter(a -> a.getRoundId().equals(item.getId())).collect(Collectors.toList());
                List<CssStudentRange> studentRange = studentRanges.stream().filter(a -> a.getRoundId().equals(item.getId())).collect(Collectors.toList());
                view.setRoundCourse(roundCourse);
                view.setStudentRange(studentRange);
                view.setBeginTime(dateFormat.format(item.getBeginTime()));
                view.setEndTime(dateFormat.format(item.getEndTime()));
                for (CssStudentRange range : studentRange) {
                    List<Student> students = studentList.stream().filter(a -> StringUtils.isNotBlank(a.getBaseCollegeId()) && a.getBaseCollegeId().equals(range.getBaseCollegeId()) && a.getGradeId().equals(range.getGradeId())).collect(Collectors.toList());
                    totalStudent += students.size();
                }

                List<String> collegeNameList = studentRange.stream().map(CssStudentRange::getCollegeName).distinct().collect(Collectors.toList());
                for (String name : collegeNameList) {
                    StudentRangeDto rangeDto = new StudentRangeDto();
                    rangeDto.setId(studentRange.stream().filter(a -> a.getCollegeName().equals(name)).findFirst().get().getBaseCollegeId());
                    rangeDto.setName(name);
                    List<String> gradeNameList = studentRange.stream().filter(a -> a.getCollegeName().equals(name)).map(CssStudentRange::getGradeName).distinct().collect(Collectors.toList());
                    List<StudentRangeChildDto> list = new ArrayList<>();
                    for (String gradeName : gradeNameList) {
                        StudentRangeChildDto rangeChildDto = new StudentRangeChildDto();
                        rangeChildDto.setName(gradeName);
                        rangeChildDto.setId(studentRange.stream().filter(a -> a.getGradeName().equals(gradeName)).findFirst().get().getGradeId());
                        List<Student> students = studentList.stream().filter(a -> StringUtils.isNotBlank(a.getCollegeName()) && a.getGradeName().equals(gradeName) && a.getCollegeName().equals(name)).collect(Collectors.toList());
                        rangeChildDto.setStudentCount(students.size());
                        list.add(rangeChildDto);
                    }
                    rangeDto.setList(list);
                    studentRangeList.add(rangeDto);
                }
                view.setStudentRangeList(studentRangeList);
                view.setStudentNum(totalStudent);
                result.add(view);
            }
        }
        //选课时间状态 0超过选课时间 1时间范围内 2未到选课时间
        result.forEach(a -> {
            try {
                Date nowDate = new Date();
                Date beginTime = dateFormat.parse(a.getBeginTime());
                Date endTime = dateFormat.parse(a.getEndTime());
                if (nowDate.compareTo(beginTime) > 0 && nowDate.compareTo(endTime) < 0) {
                    a.setTimeStatus(1);
                } else if (nowDate.compareTo(beginTime) < 0) {
                    a.setTimeStatus(2);
                }
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            for (StudentRangeDto rangeDto : a.getStudentRangeList()) {
                //排序
                List<StudentRangeChildDto> collect = rangeDto.getList().stream().sorted(Comparator.comparing(StudentRangeChildDto::getName)).collect(Collectors.toList());
                rangeDto.setList(collect);
            }
        });
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOrUpdateRound(RoundListDto param, String authorization, Integer taskId) throws UnsupportedEncodingException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        CssTaskRound round = new CssTaskRound();
        BeanUtils.copyProperties(param, round);
        try {
            if (StringUtils.isNotBlank(param.getBeginTime())) {
                round.setBeginTime(dateFormat.parse(param.getBeginTime()));
            }
            if (StringUtils.isNotBlank(param.getEndTime())) {
                round.setEndTime(dateFormat.parse(param.getEndTime()));
            }
        } catch (ParseException e) {
            throw new BizException("网络异常");
        }
        round.setTaskId(taskId);
        if (StrUtil.isNotEmpty(round.getCreatedUserName())){
            round.setCreatedUserName(URLDecoder.decode(round.getCreatedUserName(), "utf-8"));
        }
        cssTaskRoundService.saveOrUpdate(round);
        CssTaskRound cssTaskRound = cssTaskRoundService.getById(round.getId());

        //消息通知
        Instant beginInstant = cssTaskRound.getBeginTime().toInstant();
        Instant endInstant = cssTaskRound.getEndTime().toInstant();
        String model = cssTaskRound.getType().equals(1) ? "预选" : "选课";
        if (param.getIsEnable() == 1){
            yunBasicServiceImpl.sendSelectCourseStartMsg(LocalDateTime.ofInstant(beginInstant, ZoneId.systemDefault()), LocalDateTime.ofInstant(endInstant, ZoneId.systemDefault()),
                    taskId, cssTaskRound.getRoundName(), cssTaskRound.getCreatedUserId(), cssTaskRound.getCreatedUserName(), authorization);
        }

        //自学轮次-保存课程对应学生数据
        if (param.getSelectType().equals(4)) {
            if (param.getId() == null) {
                if (StringUtils.isBlank(param.getUuidForImportSelf())) throw new BizException("网络异常");
                //仅创建轮次时，更新选课范围和教学班的轮次id
                courseSelectionService.lambdaUpdate().eq(CourseSelection::getUuid, param.getUuidForImportSelf())
                        .set(CourseSelection::getRoundId, cssTaskRound.getId())
                        .set(CourseSelection::getUuid, cssTaskRound.getId())
                        .update();
                teachingClassService.lambdaUpdate().eq(TeachingClass::getStudentCampus, param.getUuidForImportSelf())
                        .set(TeachingClass::getStudentCampus, cssTaskRound.getId())
                        .update();
            } else {
                courseSelectionService.lambdaUpdate().eq(CourseSelection::getUuid, param.getUuidForImportSelf())
                        .set(CourseSelection::getRoundId, cssTaskRound.getId())
                        .set(CourseSelection::getUuid, cssTaskRound.getId())
                        .update();
            }
        }
        //正选轮次-保存轮次对应课程
        if (!param.getSelectType().equals(3) && !param.getSelectType().equals(4)) {
            CssRoundCourseService.lambdaUpdate().eq(CssRoundCourse::getRoundId, round.getId()).remove();
            List<CssSelectCourse> cssSelectCourses = this.lambdaQuery().eq(CssSelectCourse::getType, 2).eq(CssSelectCourse::getTaskId, taskId).list();
            cssSelectCourses.addAll(this.lambdaQuery().eq(CssSelectCourse::getType, 1).eq(CssSelectCourse::getTaskId, taskId).eq(CssSelectCourse::getIsEnable, 1).list());
            cssSelectCourses.forEach(a -> {
                CssRoundCourse roundCourse = new CssRoundCourse()
                        .setCourseId(a.getCourseId())
                        .setRoundId(round.getId())
                        .setTaskId(taskId);
                CssRoundCourseService.save(roundCourse);
            });
            //预选正选轮次-保存选课学生范围
            if (param.getStudentRange() != null) {
                cssStudentRangeService.lambdaUpdate().eq(CssStudentRange::getRoundId, round.getId()).eq(CssStudentRange::getTaskId, taskId).remove();
                //不传默认全校学生选课
                if (param.getStudentRange().size() == 0) {
                    List<CssStudentRange> list = new ArrayList<>();
                    List<College> colleges = collegeService.lambdaQuery().eq(College::getTaskId, taskId).list();
                    List<MajorGrade> majorGradeList = majorGradeService.lambdaQuery().eq(MajorGrade::getTaskId, taskId).list();
                    for (College college : colleges) {
                        List<String> grades = majorGradeList.stream()
                                .filter(a -> a.getBaseCollegeId().equals(college.getBaseCollegeId()))
                                .map(MajorGrade::getGradeId).distinct().collect(Collectors.toList());
                        for (String grade : grades) {
                            CssStudentRange range = new CssStudentRange()
                                    .setRoundId(round.getId())
                                    .setTaskId(taskId)
                                    .setBaseCollegeId(college.getBaseCollegeId())
                                    .setCollegeName(college.getCollegeName())
                                    .setGradeId(grade)
                                    .setGradeName(majorGradeList.stream().filter(a -> a.getGradeId().equals(grade)).findFirst().get().getGradeName());
                            list.add(range);
                        }
                    }
                    cssStudentRangeService.saveBatch(list);
                }
                //传了代表设置选课范围
                for (CssStudentRange studentRange : param.getStudentRange()) {
                    studentRange.setRoundId(round.getId());
                    studentRange.setTaskId(taskId);
                    cssStudentRangeService.saveOrUpdate(studentRange);
                }
            }
        }
        //重修轮次-同步重修学生
        if (param.getSelectType().equals(3)) {
            TaskInfo taskInfo = taskInfoService.getById(taskId);
            if (ObjUtil.isNotNull(taskInfo)) {
                List<StudentRetake> studentRetakes = studentRetakeService.lambdaQuery().eq(StudentRetake::getTaskId, taskId).list();
                if (CollUtil.isEmpty(studentRetakes)) {
                    yunBasicService.syncRetakeStudent(taskId, taskInfo.getSchoolId(), taskInfo.getTerm());
                }
            }
        }
        return true;
    }

    @Override
    public Boolean deleteRoundCourseToSelf(Integer roundId, List<Integer> courseIds, Integer taskId) {
        if (roundId == null) {
            return true;
        } else {
            courseSelectionService.lambdaUpdate().eq(CourseSelection::getRoundId, roundId)
                    .in(CourseSelection::getCourseId, courseIds).eq(CourseSelection::getTaskId, taskId).remove();
            teachingClassService.lambdaUpdate().in(TeachingClass::getCourseId, courseIds).eq(TeachingClass::getIsOptional, 1).remove();
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean copyRound(Integer id, Integer taskId) {
        try {
            CssTaskRound cssTaskRound = cssTaskRoundService.getById(id);
            cssTaskRound.setId(null);
            List<CssTaskRound> list = cssTaskRoundService.lambdaQuery()
                    .eq(CssTaskRound::getTaskId, taskId)
                    .eq(CssTaskRound::getSelectType, cssTaskRound.getSelectType())
                    .eq(CssTaskRound::getType, cssTaskRound.getType())
                    .list();
            CssTaskRound model = list.get(list.size() - 1);
            String[] str = model.getRoundName().split("第");
            Integer i = Integer.parseInt(str[1].split("轮")[0]) + 1;
            String name = str[0] + "第" + i + "轮";
            cssTaskRound.setRoundName(name);
            cssTaskRoundService.save(cssTaskRound);

            if (!cssTaskRound.getSelectType().equals(3)) {
                QueryWrapper queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("round_id", id);
                queryWrapper.eq("task_id", taskId);
                List<CssRoundCourse> cssRoundCourseList = CssRoundCourseService.list(queryWrapper);
                List<CssStudentRange> cssStudentRangeList = cssStudentRangeService.list(queryWrapper);
                List<CourseSelection> courseSelectionList = courseSelectionService.list(queryWrapper);

                for (CssRoundCourse item : cssRoundCourseList
                ) {
                    item.setRoundId(cssTaskRound.getId());
                    item.setId(null);
                    CssRoundCourseService.save(item);
                }

                if (cssTaskRound.getSelectType().equals(4)) {//自学
                    for (CourseSelection item : courseSelectionList) {
                        item.setRoundId(cssTaskRound.getId());
                        item.setId(null);
                        courseSelectionService.save(item);
                    }
                } else {
                    for (CssStudentRange item : cssStudentRangeList
                    ) {
                        item.setRoundId(cssTaskRound.getId());
                        item.setId(null);
                        cssStudentRangeService.save(item);
                    }
                }
            }
            return true;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeRound(Integer id, Integer taskId) {
        cssTaskRoundService.removeById(id);
        QueryWrapper<CssRoundCourse> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("round_id", id);
        CssRoundCourseService.remove(queryWrapper);
        QueryWrapper<CssStudentRange> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("round_id", id);
        cssStudentRangeService.remove(queryWrapper1);

        //根据轮次id删除选课课程范围表以及教学班表
        List<Long> deleteCourseIds = courseSelectionService.lambdaQuery().eq(CourseSelection::getRoundId, id).list()
                .stream().map(CourseSelection::getCourseId).distinct().collect(Collectors.toList());
        if (CollUtil.isNotEmpty(deleteCourseIds)) {
            List<Long> deleteTeachingClassIds = teachingClassService.lambdaQuery().eq(TeachingClass::getIsOptional, 1).in(TeachingClass::getCourseId, deleteCourseIds).list()
                    .stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            teachingClassService.deleteClass(deleteTeachingClassIds);
        }
        courseSelectionService.lambdaUpdate().eq(CourseSelection::getRoundId, id).remove();
        return true;
    }

    @Override
    public ResultDto<PreLogsDto> getPreLogs(Long roundId, String baseCollegeId, String gradeId, String classId, Long courseId, String startDateTime, String endDateTime, String keyword, Integer pageSize, Integer currentPage, Integer taskId) {
        ResultDto<PreLogsDto> resultDto = new ResultDto<>();
        resultDto.setCurrentPage(currentPage);
        resultDto.setPageSize(pageSize);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        CssTaskRound round = cssTaskRoundService.getById(roundId);
        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
        List<PreLogsDto> result = new ArrayList<>();
        List<Student> students = studentService.lambdaQuery()
                .eq(StringUtils.isNotBlank(baseCollegeId), Student::getBaseCollegeId, baseCollegeId)
                .eq(StringUtils.isNotBlank(gradeId), Student::getGradeId, gradeId)
                .eq(StringUtils.isNotBlank(classId), Student::getClassId, classId)
                .like(StringUtils.isNotBlank(keyword), Student::getStudentName, keyword)
                .eq(Student::getTaskId, taskId).list();
        //获取本学期所有课程id
        List<Long> courseIds = courseList.stream().map(Course::getCourseId).collect(Collectors.toList());
        List<CssPreSelectStudent> selectStudents = cssPreSelectStudentMapper.getPreSelectStudent(taskId, courseId, startDateTime, endDateTime);
        //去除不存在课程的脏数据
        selectStudents = selectStudents.stream().filter(a -> courseIds.contains(a.getCourseId())).collect(Collectors.toList());
        for (CssPreSelectStudent item : selectStudents) {
            Optional<Course> optionalCourse = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
            Optional<Student> optional = students.stream().filter(a -> a.getStudentId().equals(item.getStudentId())).findFirst();
            if (optional.isPresent() && optionalCourse.isPresent()) {
                Student student = optional.get();
                Course course = optionalCourse.get();
                PreLogsDto view = new PreLogsDto();
                BeanUtils.copyProperties(item, view);
                BeanUtils.copyProperties(student, view);
                view.setCourseName(course.getCourseName());
                view.setCourseCode(course.getCourseCode());
                result.add(view);
            }
        }
        //预选课缓存数据
        List<CssPreSelectStudent> preDataByRedis = this.getPreDataByRedis(taskId);
        for (CssPreSelectStudent item : preDataByRedis) {
            boolean isExist = selectStudents.stream().anyMatch(a -> a.getStudentId().equals(item.getStudentId())
                    && a.getCourseId().equals(item.getCourseId())
                    && a.getFlag().equals(item.getFlag()));
            if (!isExist) {
                Optional<Course> optionalCourse = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                Optional<Student> optional = students.stream().filter(a -> a.getStudentId().equals(item.getStudentId())).findFirst();
                if (optional.isPresent() && optionalCourse.isPresent()) {
                    Student student = optional.get();
                    Course course = optionalCourse.get();
                    PreLogsDto view = new PreLogsDto();
                    BeanUtils.copyProperties(item, view);
                    BeanUtils.copyProperties(student, view);
                    String format = formatter.format(view.getModifiedTime());
                    view.setModifiedTime(LocalDateTime.from(formatter.parse(format)));
                    view.setCourseName(course.getCourseName());
                    view.setCourseCode(course.getCourseCode());
                    result.add(view);
                }
            }
        }
        if (ObjUtil.isNotEmpty(courseId)) {
            result = result.stream().filter(a -> a.getCourseId().equals(courseId)).collect(Collectors.toList());
        }
        result = result.stream().sorted(Comparator.comparing(PreLogsDto::getModifiedTime).reversed()).collect(Collectors.toList());
        PageInfo<PreLogsDto> pageInfo = PagingUtil.getPages(currentPage, pageSize, result);
        resultDto.setTotal(pageInfo.getTotal());
        resultDto.setPages(pageInfo.getPages());
        resultDto.setList(pageInfo.getList());
        return resultDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDto<PreResultDto> getPreResultList(String baseCollegeId, String courseTypeId, Optional<Integer> courseNature, String keyword, Optional<Integer> isEnable, Optional<Integer> isAchieveOpen, Integer pageSize, Integer currentPage, Integer taskId) {
        ResultDto<PreResultDto> resultDto = new ResultDto<>();
        resultDto.setCurrentPage(currentPage);
        resultDto.setPageSize(pageSize);

        List<PreResultDto> result = new ArrayList<>();
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(baseCollegeId), "base_college_id", baseCollegeId);
        queryWrapper.eq(StringUtils.isNotBlank(courseTypeId), "course_type_id", courseTypeId);
        courseNature.ifPresent(a -> queryWrapper.eq("course_nature", a));
        queryWrapper.like(StringUtils.isNotBlank(keyword), "course_name", keyword);
        queryWrapper.eq("task_id", taskId);
        List<Course> courseList = courseService.list(queryWrapper);
        List<CssPreSelectStudent> selectStudents = cssPreSelectStudentService.lambdaQuery().eq(CssPreSelectStudent::getTaskId, taskId).eq(CssPreSelectStudent::getFlag, 1).list();
        //预选课缓存数据
        List<CssPreSelectStudent> redisSaveList = new ArrayList<>();
        List<CssPreSelectStudent> preDataByRedis = this.getPreDataByRedis(taskId);
        //过滤退选数据
        preDataByRedis = preDataByRedis.stream().filter(a -> a.getFlag().equals(1)).collect(Collectors.toList());
        for (CssPreSelectStudent item : preDataByRedis) {
            boolean isExist = selectStudents.stream().anyMatch(a -> a.getStudentId().equals(item.getStudentId())
                    && a.getCourseId().equals(item.getCourseId())
                    && a.getFlag().equals(item.getFlag()));
            if (!isExist) {
                redisSaveList.add(item);
                selectStudents.add(item);
            }
        }
        //预选课缓存数据删除
        String redisKey = studentServiceImpl.getCacheKeys(taskId, null, 8, null);
        String key1 = GlobalConstant.REDIS_PREFIX + taskId + StrUtil.C_COLON + "StudentOptionalCourse";
        List<Long> studentIds = studentService.lambdaQuery().eq(Student::getTaskId, taskId).list()
                .stream().map(Student::getStudentId).collect(Collectors.toList());
        String[] keys = new String[studentIds.size()];
        int i = 0;
        for (Long studentId : studentIds) {
            String key = key1 + StrUtil.C_COLON + studentId + StrUtil.C_COLON + "Primary";
            keys[i] = key;
            i += 1;
        }
        redisUtil.del(redisKey);
        redisUtil.del(keys);
        cssPreSelectStudentService.saveBatch(redisSaveList);

        List<CssSelectCourse> selectCourses = this.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId).eq(CssSelectCourse::getType, 1).list();
        for (CssSelectCourse item : selectCourses
        ) {
            Optional<Course> optional = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
            if (optional.isPresent()) {
                Course course = optional.get();
                PreResultDto view = new PreResultDto();
                BeanUtils.copyProperties(item, view);
                view.setCourseName(course.getCourseName());
                view.setCourseCode(course.getCourseCode());
                view.setBaseCollegeId(course.getBaseCollegeId());
                view.setCollegeName(course.getCollegeName());
                view.setCourseTypeId(course.getCourseTypeId());
                view.setCourseType(course.getCourseType());
                view.setCourseNature(course.getCourseNature());
                Integer studentNum = (int) selectStudents.stream().filter(a -> a.getCourseId().equals(item.getCourseId()) && a.getFlag().equals(1)).count();
                view.setStudentNum(studentNum);
                result.add(view);
            }
        }
        if (isAchieveOpen.isPresent() && isAchieveOpen.get() == 1) {
            result = result.stream().filter(a -> a.getClassNum() >= a.getStudentNum()).collect(Collectors.toList());
        }
        if (isEnable.isPresent()) {
            result = result.stream().filter(a -> a.getIsEnable().equals(isEnable.get())).collect(Collectors.toList());
        }

        PageInfo<PreResultDto> pageInfo = PagingUtil.getPages(currentPage, pageSize, result);
        resultDto.setTotal(pageInfo.getTotal());
        resultDto.setPages(pageInfo.getPages());
        resultDto.setList(pageInfo.getList());
        return resultDto;
    }

    @Override
    public Map<String, Object> publishStatistics(Integer type, Integer taskId) {
        Map<String, Object> result = new HashMap<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //各单位提交进度
        QueryWrapper<College> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("task_id", taskId);
        List<CollegePlanDto> planDtoListPre = new ArrayList<>();
        List<CollegePlanDto> planDtoListOnline = new ArrayList<>();
        List<College> colleges = collegeService.list(queryWrapper2);
        int subCountPre = 0;
        int notSubCountPre = 0;
        int subCountOnline = 0;
        int notSubCountOnline = 0;
        for (College item : colleges
        ) {
            //预选课
            CollegePlanDto viewPre = new CollegePlanDto();
            viewPre.setCollegeName(item.getCollegeName());
            viewPre.setFirstTime(item.getPreFirstTime());
            viewPre.setLatestTime(item.getPreLatestTime());
            viewPre.setPublishManName(item.getPreUserName());
            if (item.getPreFirstTime() == null) {
                viewPre.setStatus(0);
                notSubCountPre += 1;
            } else {
                viewPre.setStatus(1);
                subCountPre += 1;
            }
            planDtoListPre.add(viewPre);

            //正选
            CollegePlanDto viewOnline = new CollegePlanDto();
            viewOnline.setCollegeName(item.getCollegeName());
            viewOnline.setFirstTime(item.getSelFirstTime());
            viewOnline.setLatestTime(item.getSelLatestTime());
            viewOnline.setPublishManName(item.getSelUserName());
            if (item.getSelFirstTime() == null) {
                viewOnline.setStatus(0);
                notSubCountOnline += 1;
            } else {
                viewOnline.setStatus(1);
                subCountOnline += 1;
            }
            planDtoListOnline.add(viewOnline);
        }

        result.put("totalSelectNum", 0);
        result.put("realySelectNum", 0);
        result.put("unSelectNum", 0);
        result.put("coursetNum", 0);
        result.put("selectClassNum", 0);
        result.put("isAchieveOpen", 0);
        result.put("notAchieveOpen", 0);
        result.put("isEnableNum", 0);
        result.put("notEnableNum", 0);
        result.put("cancelClassNum", 0);
        result.put("openClassNum", 0);
        List<Student> students = studentService.lambdaQuery().eq(Student::getTaskId, taskId).list();
        int isAchieveOpen = 0;
        int notAchieveOpen = 0;
        if (type.equals(1)) {
            //已提交
            result.put("subCount", subCountPre);
            //未提交
            result.put("notSubCount", notSubCountPre);
            //开课单位数
            result.put("collegeCount", colleges.size());
            //开课单位详情
            result.put("collegeDetail", planDtoListPre);
            //获取所有预选选课轮次
            List<CssTaskRound> cssTaskRoundList = cssTaskRoundService.lambdaQuery().eq(CssTaskRound::getTaskId, taskId).eq(CssTaskRound::getType, 1).list();
            List<Integer> roundIds = cssTaskRoundList.stream().map(CssTaskRound::getId).collect(Collectors.toList());
            if (CollUtil.isEmpty(roundIds)) {
                return result;
            }
            List<CssStudentRange> cssStudentRangeList = cssStudentRangeService.lambdaQuery().eq(CssStudentRange::getTaskId, taskId).in(CssStudentRange::getRoundId, roundIds).list();
            List<Student> totalSelectList = new ArrayList<>();
            for (CssStudentRange studentRange : cssStudentRangeList) {
                List<Student> studentList = students.stream().filter(a -> a.getBaseCollegeId().equals(studentRange.getBaseCollegeId()) && a.getGradeId().equals(studentRange.getGradeId())).collect(Collectors.toList());
                totalSelectList.addAll(studentList);
            }
            totalSelectList = totalSelectList.stream().distinct().collect(Collectors.toList());
            //应选课学生总数
            result.put("totalSelectNum", totalSelectList.size());

            List<Long> studentIds = totalSelectList.stream().map(Student::getStudentId).collect(Collectors.toList());
            if (CollUtil.isEmpty(studentIds)) {
                return result;
            }
            List<CssPreSelectStudent> cssPreSelectStudentList = cssPreSelectStudentService.lambdaQuery()
                    .eq(CssPreSelectStudent::getTaskId, taskId).eq(CssPreSelectStudent::getFlag, 1).in(CssPreSelectStudent::getStudentId, studentIds).list();
            List<Long> selectStudentIds = cssPreSelectStudentList.stream().map(CssPreSelectStudent::getStudentId).distinct().collect(Collectors.toList());
            //实际选课人数
            result.put("realySelectNum", selectStudentIds.size());
            //未选课数
            result.put("unSelectNum", totalSelectList.size() - selectStudentIds.size());

            List<CssSelectCourse> cssSelectCourseList = cssSelectCourseService.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId).eq(CssSelectCourse::getType, type).list();
            //选课课程数
            result.put("coursetNum", cssSelectCourseList.size());
            if (CollUtil.isEmpty(cssSelectCourseList)) {
                return result;
            }
            for (CssSelectCourse item : cssSelectCourseList) {
                long studentNum = cssPreSelectStudentList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).count();
                if (item.getClassNum() <= studentNum) {
                    isAchieveOpen += 1;
                } else {
                    notAchieveOpen += 1;
                }
            }
            //达到开课条件
            result.put("isAchieveOpen", isAchieveOpen);
            //未到开课条件
            result.put("notAchieveOpen", notAchieveOpen);
            //开课数
            result.put("isEnableNum", (int) cssSelectCourseList.stream().filter(a -> a.getIsEnable().equals(1)).count());
            //未开课数
            result.put("notEnableNum", (int) cssSelectCourseList.stream().filter(a -> a.getIsEnable().equals(0)).count());
        } else if (type.equals(2)) {
            //已提交
            result.put("subCount", subCountOnline);
            //未提交
            result.put("notSubCount", notSubCountOnline);
            //开课单位数
            result.put("collegeCount", colleges.size());
            //开课单位详情
            result.put("collegeDetail", planDtoListOnline);
            //获取所有正选选课轮次
            List<CssTaskRound> cssTaskRoundList = cssTaskRoundService.lambdaQuery().eq(CssTaskRound::getTaskId, taskId).eq(CssTaskRound::getType, 2).list();
            List<Integer> roundIds = cssTaskRoundList.stream().map(CssTaskRound::getId).collect(Collectors.toList());
            if (CollUtil.isEmpty(roundIds)) {
                return result;
            }
            //获取所有正选轮次的选课范围
            List<CssStudentRange> cssStudentRangeList = cssStudentRangeService.lambdaQuery()
                    .eq(CssStudentRange::getTaskId, taskId).in(CssStudentRange::getRoundId, roundIds).list();
            List<Student> totalSelectList = new ArrayList<>();
            for (CssStudentRange studentRange : cssStudentRangeList) {
                List<Student> studentList = students.stream().filter(a -> a.getBaseCollegeId().equals(studentRange.getBaseCollegeId())
                        && a.getGradeId().equals(studentRange.getGradeId())).collect(Collectors.toList());
                totalSelectList.addAll(studentList);
            }
            totalSelectList = totalSelectList.stream().distinct().collect(Collectors.toList());
            //应选课学生总数
            result.put("totalSelectNum", totalSelectList.size());

            List<Long> studentIds = totalSelectList.stream().map(Student::getStudentId).collect(Collectors.toList());
            if (CollUtil.isEmpty(studentIds)) {
                return result;
            }
            //轮次选课课程
            List<Long> selectCourseIds = cssSelectCourseService.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId).eq(CssSelectCourse::getIsEnable, 1).list()
                    .stream().map(CssSelectCourse::getCourseId).collect(Collectors.toList());
            if (CollUtil.isEmpty(selectCourseIds)) {
                return result;
            }
            //选课课程数
            result.put("coursetNum", selectCourseIds.size());
            //选课教学班
            List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId)
                    .in(TeachingClass::getCourseId, selectCourseIds)
                    .ne(TeachingClass::getTeachingClassType, 0)
                    .eq(TeachingClass::getIsOptional, 0)
                    .eq(TeachingClass::getIsEnable, 0)
                    .list();
            result.put("selectClassNum", teachingClassList.size());
            //开班教学班
            result.put("openClassNum", teachingClassList.size());
            List<Long> teachingClassIds = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            if (CollUtil.isEmpty(teachingClassIds)) {
                return result;
            }
            List<TeachingClassStudent> teachingClassStudentList = teachingClassStudentService.lambdaQuery()
                    .in(TeachingClassStudent::getTeachingClassId, teachingClassIds).list();
            List<TeachingClassStudent> selectDataByRedis = this.getSelectDataByRedis(taskId, teachingClassList);
            //避免重复数据
            for (TeachingClassStudent item : selectDataByRedis) {
                if (teachingClassStudentList.stream().noneMatch(a -> a.getStudentId().equals(item.getStudentId())
                        && a.getTeachingClassId().equals(item.getTeachingClassId())
                        && a.getFlag().equals(item.getFlag()))) {
                    teachingClassStudentList.add(item);
                }
            }
            List<Long> selectStudentIds = teachingClassStudentList.stream().map(TeachingClassStudent::getStudentId).distinct().collect(Collectors.toList());
            //实际选课人数
            result.put("realySelectNum", selectStudentIds.size());
            //未选课数
            result.put("unSelectNum", totalSelectList.size() - selectStudentIds.size());
            List<DeleteClass> deleteClassList = deleteClassService.lambdaQuery().eq(DeleteClass::getTaskId, taskId).list();
            //取消开班教学班
            result.put("cancelClassNum", deleteClassList.size());

            CssTaskInfo cssTaskInfo = cssTaskInfoService.lambdaQuery().eq(CssTaskInfo::getTaskId, taskId).eq(CssTaskInfo::getType, 2).one();
            if (cssTaskInfo == null || ObjUtil.isEmpty(cssTaskInfo.getClassNum())) {
                return result;
            }
            Long classNum = Long.valueOf(cssTaskInfo.getClassNum());
            for (TeachingClass item : teachingClassList) {
                long studentNum = teachingClassStudentList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).count();
                if (classNum > studentNum) {
                    notAchieveOpen += 1;
                }
            }
            //未到开课/开班条件
            result.put("notAchieveOpen", notAchieveOpen);
        }
        return result;
    }

    @Override
    public ResultDto<StudentDto> getStudentList(String baseCollegeId, String gradeId, Optional<Integer> classId, Optional<Integer> isSelect, String keyword, Integer pageSize, Integer currentPage, Integer taskId) {
        ResultDto<StudentDto> result = new ResultDto<>();
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(baseCollegeId), "base_college_id", baseCollegeId);
        queryWrapper.eq(StringUtils.isNotBlank(gradeId), "grade_id", gradeId);
        classId.ifPresent(q -> queryWrapper.eq("class_id", q));
        queryWrapper.like(StringUtils.isNotBlank(keyword), "student_name", keyword);
        queryWrapper.eq("task_id", taskId);
        Page page = new Page(currentPage, pageSize);
        List<Student> studentList = studentService.page(page, queryWrapper).getRecords();

        QueryWrapper<CssPreSelectStudent> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("task_id", taskId);
        List<CssPreSelectStudent> selectStudents = cssPreSelectStudentService.list(queryWrapper1);
        List<StudentDto> studentDtoList = new ArrayList<>();
        for (Student item : studentList
        ) {
            StudentDto view = new StudentDto();
            BeanUtils.copyProperties(item, view);
            List<CssPreSelectStudent> selectCourse = selectStudents.stream().filter(a -> a.getStudentId().equals(item.getStudentId())).collect(Collectors.toList());
            if (selectCourse.size() > 0) {
                view.setSelectCourseNum(selectCourse.size());
            }
            studentDtoList.add(view);
        }
        result.setList(studentDtoList);
        result.setPageSize(pageSize);
        result.setCurrentPage(currentPage);
        result.setTotal(page.getTotal());
        result.setPages(page.getPages());
        return result;
    }

    @Override
    public ResultDto<TeachingClassDto> getTeachingClassList(String baseCollegeId, String courseTypeId, Integer courseNature, Integer courseId, String keyword, Integer pageSize, Integer currentPage, Integer taskId) {
        ResultDto<TeachingClassDto> result = new ResultDto<>();
        List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery().eq(StringUtils.isNotBlank(baseCollegeId), TeachingClass::getBaseCollegeId, baseCollegeId)
                .eq(courseId != null, TeachingClass::getCourseId, courseId)
                .like(StringUtils.isNotBlank(keyword), TeachingClass::getTeachingClassName, keyword)
                .eq(TeachingClass::getTaskId, taskId).list();
        List<TeachingClassDto> teachingClassDtoList = new ArrayList<>();
        for (TeachingClass item : teachingClasses
        ) {
            TeachingClassDto view = new TeachingClassDto();
            BeanUtils.copyProperties(item, view);
            teachingClassDtoList.add(view);
        }
        PageInfo<TeachingClassDto> pageInfo = PagingUtil.getPages(currentPage, pageSize, teachingClassDtoList);
        result.setCurrentPage(currentPage);
        result.setPageSize(pageSize);
        result.setList(pageInfo.getList());
        result.setTotal(pageInfo.getTotal());
        result.setPages(pageInfo.getPages());
        return result;
    }

    @Override
    public List<StudentRangeDto> getStudentRangeList(Integer flag, Integer taskId) {
        List<StudentRangeDto> result = new ArrayList<>();
        QueryWrapper<MajorGrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_id", taskId);
        List<MajorGrade> collegeList = majorGradeService.list(queryWrapper);
        List<String> collegeNameList = collegeList.stream().map(MajorGrade::getCollegeName).distinct().collect(Collectors.toList());
        List<String> gradeNameList = collegeList.stream().map(MajorGrade::getGradeName).distinct().collect(Collectors.toList());
        QueryWrapper<Student> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("task_id", taskId);
        List<Student> students = studentService.list(queryWrapper1);
        //过滤没有学院、年级的学生（有些sb环境还真存在这种数据）
        students = students.stream().filter(a -> StringUtils.isNotBlank(a.getCollegeName()) && StringUtils.isNotBlank(a.getGradeName())).collect(Collectors.toList());
        Integer TotalStudent = 0;
        if (flag == 0) {
            for (String collegeName : collegeNameList
            ) {
                StudentRangeDto view = new StudentRangeDto();
                String collegeId = collegeList.stream().filter(a -> a.getCollegeName().equals(collegeName)).findFirst().get().getBaseCollegeId();
                view.setId(collegeId);
                view.setName(collegeName);
                List<String> GradeIdList = collegeList.stream().filter(a -> a.getCollegeName().equals(collegeName)).map(MajorGrade::getGradeId).distinct().collect(Collectors.toList());
                List<StudentRangeChildDto> list = new ArrayList<>();
                for (String gradeId : GradeIdList
                ) {
                    StudentRangeChildDto childView = new StudentRangeChildDto();
                    String gradeName = collegeList.stream().filter(a -> a.getGradeId().equals(gradeId)).findFirst().get().getGradeName();
                    childView.setId(gradeId);
                    childView.setName(gradeName);
                    List<Student> studentList = students.stream().filter(a -> a.getCollegeName().equals(collegeName) && a.getGradeName().equals(gradeName)).collect(Collectors.toList());
                    childView.setStudents(studentList);
                    list.add(childView);
                    TotalStudent += studentList.size();
                }
                view.setList(list);
                view.setTotalStudent(TotalStudent);
                result.add(view);
            }
        } else {
            for (String gradeName : gradeNameList
            ) {
                StudentRangeDto view = new StudentRangeDto();
                view.setId(collegeList.stream().filter(a -> a.getGradeName().equals(gradeName)).findFirst().get().getGradeId());
                view.setName(gradeName);
                List<String> collegeIdList = collegeList.stream().filter(a -> a.getGradeName().equals(gradeName)).map(MajorGrade::getBaseCollegeId).distinct().collect(Collectors.toList());
                List<StudentRangeChildDto> list = new ArrayList<>();
                for (String collegeId : collegeIdList
                ) {
                    StudentRangeChildDto childView = new StudentRangeChildDto();
                    String collegeName = collegeList.stream().filter(a -> a.getBaseCollegeId().equals(collegeId)).findFirst().get().getCollegeName();
                    childView.setId(collegeId);
                    childView.setName(collegeName);
                    List<Student> studentList = students.stream().filter(a -> a.getCollegeName().equals(collegeName) && a.getGradeName().equals(gradeName)).collect(Collectors.toList());
                    childView.setStudents(studentList);
                    list.add(childView);
                    TotalStudent += studentList.size();
                }
                view.setList(list);
                view.setTotalStudent(TotalStudent);
                result.add(view);
            }
        }
        return result;
    }

    @Override
    public List<CourseRangeDto> getClassRangeList(String baseCollegeId, String courseTypeId, String courseNature, String keyword, List<CssStudentRange> rangeList, Integer taskId) {
        List<CourseRangeDto> result = new ArrayList<>();
        List<Course> courseList = courseService.lambdaQuery()
                .eq(StringUtils.isNotBlank(baseCollegeId), Course::getBaseCollegeId, baseCollegeId)
                .eq(StringUtils.isNotBlank(courseTypeId), Course::getCourseTypeId, courseTypeId)
                .eq(StringUtils.isNotBlank(courseNature), Course::getCourseNature, courseNature)
                .eq(Course::getTaskId, taskId)
                .like(StringUtils.isNotBlank(keyword), Course::getCourseName, keyword)
                .list();
        List<PlanTeaching> planTeachingList = planTeachingService.lambdaQuery().eq(PlanTeaching::getTaskId, taskId).list();
        List<PlanTeachingCourse> planTeachingCourseList = planTeachingCourseService.lambdaQuery().eq(PlanTeachingCourse::getTaskId, taskId).list();
        if (CollUtil.isEmpty(rangeList)) {
            for (Course course : courseList
            ) {
                CourseRangeDto view = new CourseRangeDto();
                view.setCourseName(course.getCourseName());
                view.setCourseNature(course.getCourseNature());
                view.setCourseType(course.getCourseType());
                view.setCollegeName(course.getCollegeName());
                view.setTaskId(taskId);
                view.setCourseId(course.getCourseId());
                result.add(view);
            }
        } else {
            for (CssStudentRange range : rangeList
            ) {
                Optional<PlanTeaching> planTeaching = planTeachingList.stream().filter(a -> a.getCollegeName().equals(range.getCollegeName()) && a.getGradeName().equals(range.getGradeName())).findFirst();
                if (planTeaching.isPresent()) {
                    String baseTeachingPlanId = planTeaching.get().getBaseTeachingPlanId();
                    List<PlanTeachingCourse> planTeachingCourse = planTeachingCourseList.stream().filter(a -> a.getBaseTeachingPlanId().equals(baseTeachingPlanId)).collect(Collectors.toList());
                    for (PlanTeachingCourse item : planTeachingCourse
                    ) {
                        CourseRangeDto view = new CourseRangeDto();
                        Course course = courseList.stream().filter(a -> a.getBaseCourseId().equals(item.getBaseCourseId())).findFirst().get();
                        view.setCourseName(course.getCourseName());
                        view.setCourseNature(course.getCourseNature());
                        view.setCourseType(course.getCourseType());
                        view.setCollegeName(course.getCollegeName());
                        view.setTaskId(taskId);
                        view.setCourseId(course.getCourseId());
                        result.add(view);
                    }
                }
            }
        }
        return result.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public Boolean setCourseStatus(List<Integer> idList, Integer isEnable, String reason, Integer remindWay, Integer taskId) {
        courseService.lambdaUpdate()
                .eq(Course::getTaskId, taskId)
                .in(Course::getCourseId, idList)
                .set(Course::getIsEnable, isEnable == 1 ? 1 : 0)
                .set(Course::getIsSelect, isEnable == 1 ? 1 : 0)
                .set(Course::getDescription, reason)
                .update();
        cssSelectCourseService.lambdaUpdate()
                .in(CssSelectCourse::getCourseId, idList)
                .eq(CssSelectCourse::getTaskId, taskId)
                .set(CssSelectCourse::getIsEnable, isEnable == 1 ? 1 : 0)
                .set(CssSelectCourse::getDescription, reason)
                .update();
        //通知暂定
        return true;
    }

    @Override
    public Boolean confirmPreResult(List<String> baseCollegeIdList, String userId, String userName, Integer type, Integer taskId) {
        List<College> collegeList = collegeService.lambdaQuery().eq(College::getTaskId, taskId).list();
        if (CollUtil.isEmpty(baseCollegeIdList)) {
            //前端不传 == 教务管理员提交全部学院
            baseCollegeIdList = collegeList.stream().map(College::getBaseCollegeId).collect(Collectors.toList());
        }
        List<College> todoColleges = new ArrayList<>();
        if (type == 1) {
            for (String baseCollegeId : baseCollegeIdList
            ) {
                List<College> colleges = collegeList.stream().filter(a -> a.getBaseCollegeId().equals(baseCollegeId)).collect(Collectors.toList());
                for (College item : colleges
                ) {
                    if (item.getPreFirstTime() == null) {
                        item.setPreFirstTime(LocalDateTime.now());
                    }
                    item.setPreLatestTime(LocalDateTime.now());
                    item.setPreUserId(userId);
                    try {
                        item.setPreUserName(URLDecoder.decode(userName, "utf-8"));
                    } catch (UnsupportedEncodingException e) {
                        throw new RuntimeException(e);
                    }
                    todoColleges.add(item);
                }
            }
        } else if (type == 2) {
            for (String baseCollegeId : baseCollegeIdList
            ) {
                List<College> colleges = collegeList.stream().filter(a -> a.getBaseCollegeId().equals(baseCollegeId)).collect(Collectors.toList());
                for (College item : colleges
                ) {
                    if (item.getSelFirstTime() == null) {
                        item.setSelFirstTime(LocalDateTime.now());
                    }
                    item.setSelLatestTime(LocalDateTime.now());
                    item.setSelUserId(userId);
                    try {
                        item.setSelUserName(URLDecoder.decode(userName, "utf-8"));
                    } catch (UnsupportedEncodingException e) {
                        throw new RuntimeException(e);
                    }
                    todoColleges.add(item);
                }
            }
        }

        collegeService.updateBatchById(todoColleges);
        return true;
    }

    @Override
    public ResultDto<MajorGrade> getCourseByMajor(String baseCollegeId, String gradeId, String baseMajorId, String keyword, Integer pageSize, Integer currentPage, Integer taskId) {
        ResultDto<MajorGrade> result = new ResultDto<>();
        result.setPageSize(pageSize);
        result.setCurrentPage(currentPage);
        QueryWrapper<MajorGrade> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(baseCollegeId), "base_college_id", baseCollegeId);
        queryWrapper.eq(StringUtils.isNotBlank(gradeId), "grade_id", gradeId);
        queryWrapper.eq(StringUtils.isNotBlank(baseMajorId), "base_major_id", baseMajorId);
        queryWrapper.like(StringUtils.isNotBlank(keyword), "major_name", keyword);
        queryWrapper.eq("task_id", taskId);
        Page page = new Page(currentPage, pageSize);
        List<MajorGrade> majorGradeList = majorGradeService.page(page, queryWrapper).getRecords();
//        List<MajorGrade> majorGradeList = majorGradeService.lambdaQuery()
//                .eq(StringUtils.isNotBlank(baseCollegeId), MajorGrade::getBaseCollegeId, baseCollegeId)
//                .eq(StringUtils.isNotBlank(gradeId), MajorGrade::getGradeId, gradeId)
//                .eq(StringUtils.isNotBlank(baseMajorId), MajorGrade::getBaseMajorId, baseMajorId)
//                .like(StringUtils.isNotBlank(keyword), MajorGrade::getMajorName, keyword)
//                .page(page).getRecords();
        result.setList(majorGradeList);
        result.setTotal(page.getTotal());
        result.setPages(page.getPages());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setCourseByMajor(List<Integer> idList, Double preCreditLimit, Integer preCourseLimit, Double creditLimit, Integer courseLimit, Integer flag, Integer selectionScope, Integer taskId, Integer selectionScopePre) {
        //按专业
        if (flag == 1) {
            for (Integer id : idList
            ) {
                MajorGrade model = majorGradeService.getById(id);
                model.setPreCourseLimit(preCourseLimit);
                model.setPreCreditLimit(preCreditLimit);
                model.setCreditLimit(creditLimit);
                model.setCourseLimit(courseLimit);
                majorGradeService.updateById(model);
                //更新该专业学生
                studentService.lambdaUpdate()
                        .eq(Student::getMajorId, model.getBaseMajorId())
                        .eq(Student::getBaseCollegeId, model.getBaseCollegeId())
                        .eq(Student::getGradeId, model.getGradeId())
                        .set(Student::getPreCourseLimit, preCourseLimit)
                        .set(Student::getPreCreditLimit, preCreditLimit)
                        .set(Student::getCourseLimit, courseLimit)
                        .set(Student::getCreditLimit, creditLimit)
                        .update();
            }
        } else {
            //按学生
            for (Integer id : idList
            ) {
                Student model = studentService.getById(id);
                model.setPreCourseLimit(preCourseLimit);
                model.setPreCreditLimit(preCreditLimit);
                model.setCreditLimit(creditLimit);
                model.setCourseLimit(courseLimit);
                model.setSelectionScope(selectionScope);
                model.setSelectionScopePre(selectionScopePre);
                studentService.updateById(model);

            }
        }
        return true;
    }

    @Override
    public ResultDto<TeachingClassDto> getTeachingClassListByStudent(Integer studentId, Integer pageSize, Integer currentPage, Integer taskId) {
        ResultDto<TeachingClassDto> result = new ResultDto<>();
        result.setCurrentPage(currentPage);
        result.setPageSize(pageSize);
        List<TeachingClassDto> list = new ArrayList<>();

        QueryWrapper<TeachingClassStudent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_id", taskId);
        queryWrapper.eq("student_id", studentId);
        queryWrapper.eq("flag", 1);
        List<TeachingClassStudent> teachingClassStudentList = teachingClassStudentService.list(queryWrapper);

        QueryWrapper<TeachingClass> wrapper = new QueryWrapper<>();
        wrapper.eq("task_id", taskId);
        List<TeachingClass> teachingClassList = teachingClassService.list(wrapper);

        QueryWrapper<TeachingClassWeek> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("task_id", taskId);
        List<TeachingClassWeek> teachingClassWeekList = teachingClassWeekService.list(queryWrapper1);

        for (TeachingClassStudent item : teachingClassStudentList
        ) {
            TeachingClassDto view = new TeachingClassDto();
            BeanUtils.copyProperties(item, view);
            Optional<TeachingClass> optionalTeachingClass = teachingClassList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).findFirst();
            if (optionalTeachingClass.isPresent()) {
                TeachingClass teachingClass = optionalTeachingClass.get();
                BeanUtils.copyProperties(teachingClass, view);
            }
            Optional<TeachingClassWeek> optional = teachingClassWeekList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).findFirst();
            if (optional.isPresent()) {
                TeachingClassWeek teachingClassWeek = optional.get();
                BeanUtils.copyProperties(teachingClassWeek, view);
            }
            list.add(view);
        }
        PageInfo<TeachingClassDto> pageInfo = PagingUtil.getPages(currentPage, pageSize, list);
        result.setTotal(pageInfo.getTotal());
        result.setPages(pageInfo.getPages());
        result.setList(pageInfo.getList());
        return result;
    }

    @Override
    public ResultDto<CssLogsDto> getCssLogs(Long roundId, String baseCollegeId, String gradeId, String classId, Optional<Integer> courseId, String startDateTime, String endDateTime, String keyword, Integer pageSize, Integer currentPage, Integer taskId) {
        try {
            ResultDto<CssLogsDto> resultDto = new ResultDto<>();
            resultDto.setCurrentPage(currentPage);
            resultDto.setPageSize(pageSize);
            CssTaskRound round = cssTaskRoundService.getById(roundId);

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            List<CssLogsDto> result = new ArrayList<>();
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(baseCollegeId), "base_college_id", baseCollegeId);
            queryWrapper.eq(StringUtils.isNotBlank(gradeId), "grade_id", gradeId);
            queryWrapper.eq(StringUtils.isNotBlank(classId), "class_id", classId);
            queryWrapper.like(StringUtils.isNotBlank(keyword), "student_name", keyword);
            queryWrapper.eq("task_id", taskId);
            List<Student> students = studentService.list(queryWrapper);
            List<Long> studentIds = students.stream().map(Student::getStudentId).collect(Collectors.toList());

            QueryWrapper<TeachingClass> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("task_id", taskId);
            queryWrapper1.ne("teaching_class_type", 0);
            queryWrapper1.isNull("unique_shift_sign");
            if (round != null && round.getSelectType().equals(4)) {
                queryWrapper1.eq("student_campus", roundId.toString());
            }
            List<TeachingClass> teachingClassList = teachingClassService.list(queryWrapper1);
            List<Long> teachingClassIds = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());

            QueryWrapper<TeachingClassStudent> wrapper = new QueryWrapper<>();
            if (CollUtil.isEmpty(teachingClassIds) || CollUtil.isEmpty(studentIds)) {
                return resultDto;
            }
            wrapper.in("teaching_class_id", teachingClassIds);
            wrapper.in("student_id", studentIds);
            if (StringUtils.isNotBlank(startDateTime)) {
                wrapper.ge("modified_time", dateFormat.parse(startDateTime));
            }
            if (StringUtils.isNotBlank(endDateTime)) {
                wrapper.le("modified_time", dateFormat.parse(endDateTime));
            }
            if (roundId != null) {
                if (roundId.equals(0L)) {
                    wrapper.eq("round_id", roundId);
                } else {
                    wrapper.and(a -> a.ne("round_id", 0).or().isNull("round_id"));
                }
            }
            courseId.ifPresent(a -> wrapper.eq("course_id", a));
            wrapper.eq("flag", 1);
            wrapper.isNotNull("modified_time");
            List<TeachingClassStudent> teachingClassStudentList = teachingClassStudentService.list(wrapper);

            List<TeachingClassStudent> selectDataByRedis = this.getSelectDataByRedis(taskId, teachingClassList);
            //避免重复数据
            for (TeachingClassStudent item : selectDataByRedis) {
                if (roundId != null && roundId.equals(0L)) {
                    break;
                }
                if (teachingClassStudentList.stream().noneMatch(a -> a.getStudentId().equals(item.getStudentId())
                        && a.getTeachingClassId().equals(item.getTeachingClassId())
                        && a.getFlag().equals(item.getFlag()))) {
                    //redis数据时间筛选
                    if (StringUtils.isNotBlank(startDateTime)) {
                        Date date = Date.from(item.getModifiedTime().atZone(ZoneId.systemDefault()).toInstant());
                        if (date.before(dateFormat.parse(startDateTime))) {
                            continue;
                        }
                    }
                    if (StringUtils.isNotBlank(endDateTime)) {
                        Date date = Date.from(item.getModifiedTime().atZone(ZoneId.systemDefault()).toInstant());
                        if (date.after(dateFormat.parse(endDateTime))) {
                            continue;
                        }
                    }

                    teachingClassStudentList.add(item);
                }
            }

            List<Teacher> teacherList = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId).list();
            List<TeachingClassTeacher> teachingClassTeacherList = teachingClassTeacherService.list();
            List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
            //获取数据
            for (TeachingClassStudent item : teachingClassStudentList) {
                CssLogsDto view = new CssLogsDto();
                BeanUtils.copyProperties(item, view);
                Optional<Student> optionalStudent = students.stream().filter(a -> a.getStudentId().equals(item.getStudentId())).findFirst();
                if (optionalStudent.isPresent()) {
                    Student student = optionalStudent.get();
                    BeanUtils.copyProperties(student, view);
                }
                Optional<TeachingClass> optionalTeachingClass = teachingClassList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).findFirst();
                if (optionalTeachingClass.isPresent()) {
                    TeachingClass teachingClass = optionalTeachingClass.get();
                    Course course = courseList.stream().filter(a -> a.getCourseId().equals(teachingClass.getCourseId())).findFirst().get();
                    view.setCourseId(teachingClass.getCourseId());
                    view.setCourseName(teachingClass.getCourseName());
                    view.setCourseCode(course.getCourseCode());
                    view.setTeachingClassName(teachingClass.getTeachingClassName());
                    List<TeachingClassTeacher> list = teachingClassTeacherList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).collect(Collectors.toList());
                    for (TeachingClassTeacher model : list
                    ) {
                        Optional<Teacher> optionalTeacher = teacherList.stream().filter(a -> a.getTeacherId().equals(model.getTeacherId())).findFirst();
                        if (optionalTeacher.isPresent()) {
                            Teacher teacher = optionalTeacher.get();
                            if (teacher.getIdentity() == 1) {
                                view.setTeacherName(teacher.getTeacherName() + teacher.getTeacherId());
                            } else {
                                view.setAssistantName(teacher.getTeacherName() + teacher.getTeacherId());
                            }
                        }
                    }
                }
                result.add(view);
            }
            PageInfo<CssLogsDto> pageInfo = PagingUtil.getPages(currentPage, pageSize, result);
            resultDto.setTotal(pageInfo.getTotal());
            resultDto.setPages(pageInfo.getPages());
            resultDto.setList(pageInfo.getList());
            return resultDto;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Boolean addTempCourse(List<CssSelectCourse> list, Integer type, Integer taskId) {
        if (CollUtil.isNotEmpty(list)) {
            List<CssSelectCourse> data = this.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId).list();
            List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
            List<CssSelectCourse> todoList = new ArrayList<>();
            List<Course> todoCourseList = new ArrayList<>();
            for (CssSelectCourse item : list) {
                //已存在
                boolean existFlag = data.stream().anyMatch(a -> a.getCourseId().equals(item.getCourseId()) && a.getType().equals(type) && a.getIsEnable().equals(1));
                if (existFlag) {
                    throw new BizException("【" + courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst().get().getCourseName() + "】已添加，请刷新重试");
                }
                //被取消开课的
                Optional<CssSelectCourse> cancelFlag = data.stream()
                        .filter(a -> a.getCourseId().equals(item.getCourseId()) && a.getType().equals(type) && a.getIsEnable().equals(0)).findFirst();
                if (cancelFlag.isPresent()) {
                    CssSelectCourse cssSelectCourse = cancelFlag.get();
                    cssSelectCourse.setIsEnable(1);
                    this.updateById(cssSelectCourse);
                    continue;
                }
                if (type == 1) {
                    Optional<Course> optional = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                    if (optional.isPresent()) {
                        Course course = optional.get();
                        course.setIsSelect(course.getIsSelect() == 2 ? 3 : 1);
                        todoCourseList.add(course);
                    }
                } else if (type == 2) {
                    Optional<Course> optional = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                    if (optional.isPresent()) {
                        Course course = optional.get();
                        course.setIsSelect(course.getIsSelect() == 1 ? 3 : 2);
                        todoCourseList.add(course);
                    }
                }
                todoList.add(item);
            }
            this.saveBatch(todoList);
            courseService.updateBatchById(todoCourseList);
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean deleteTempCourse(List<Long> IdList, Integer type, Integer taskId) {
        if (CollUtil.isNotEmpty(IdList)) {
            for (Long courseId : IdList) {
                List<Long> ids = teachingClassService.lambdaQuery()
                        .eq(TeachingClass::getCourseId, courseId).list()
                        .stream().map(TeachingClass::getTeachingClassId)
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(ids)) {
                    teachingClassService.deleteClass(ids);
                }
            }
            List<CssSelectCourse> list = this.lambdaQuery()
                    .eq(CssSelectCourse::getTaskId, taskId)
                    .in(CssSelectCourse::getId, IdList)
                    .eq(CssSelectCourse::getType, type)
                    .list();
            List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
            for (CssSelectCourse item : list) {
                if (type == 1) {
                    Optional<Course> optional = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                    if (optional.isPresent()) {
                        Course course = optional.get();
                        course.setIsSelect(course.getIsSelect() == 3 ? 2 : 0);
                        courseService.updateById(course);
                    }
                } else if (type == 2) {
                    Optional<Course> optional = courseList.stream().filter(a -> a.getCourseId().equals(item.getCourseId())).findFirst();
                    if (optional.isPresent()) {
                        Course course = optional.get();
                        course.setIsSelect(course.getIsSelect() == 3 ? 1 : 0);
                        courseService.updateById(course);
                    }
                }
            }

            this.removeByIds(IdList);
        }
        return true;
    }

    @Override
    public List<RoundListDto> getRoundListSelf(Integer taskId) {
        List<RoundListDto> roundListDtoList = new ArrayList<>();

        //1.先查询所有的轮次信息
        List<CssTaskRound> cssTaskRoundList = cssTaskRoundService.lambdaQuery().eq(CssTaskRound::getTaskId, taskId).list();
        //设值
        cssTaskRoundList.forEach(cssTaskRound -> {
            RoundListDto view = new RoundListDto();
            BeanUtils.copyProperties(cssTaskRound, view);
            //通过id在css_student_range表中找到符合条件的选课院系和学生范围
            List<CssStudentRange> list = cssStudentRangeService.lambdaQuery().eq(CssStudentRange::getRoundId, cssTaskRound.getId()).list();

            //根据baseCollegeId分组
            Map<String, List<CssStudentRange>> collect = list.stream().collect(Collectors.groupingBy(CssStudentRange::getBaseCollegeId));
            List<RoundListDto.CollegeDtoList> collegeDtoListList = new ArrayList<>();
            for (Map.Entry<String, List<CssStudentRange>> entry : collect.entrySet()) {
                String baseCollegeId = entry.getKey();
                List<CssStudentRange> cssStudentRangeList = entry.getValue();
                BeanUtils.copyProperties(cssTaskRound, view);

                RoundListDto.CollegeDtoList collegeDtoList = new RoundListDto.CollegeDtoList();
                collegeDtoList.setBaseCollegeId(baseCollegeId);
                collegeDtoList.setCollegeName(cssStudentRangeList.get(0).getCollegeName());

                List<RoundListDto.GradesDTO> gradesDTOList = cssStudentRangeList.stream().map(student -> {
                    RoundListDto.GradesDTO gradesDTO = new RoundListDto.GradesDTO();
                    gradesDTO.setGradeName(student.getGradeName());
                    gradesDTO.setGradeID(student.getGradeId());
                    return gradesDTO;
                }).collect(Collectors.toList());

                collegeDtoList.setGradesDTOList(gradesDTOList);
                collegeDtoListList.add(collegeDtoList);
            }
            view.setCollegeDtoLists(collegeDtoListList);
            roundListDtoList.add(view);
        });

        return roundListDtoList;
    }

    @Override
    public List<BaseCourse> getBaseCourse(String schoolId, Integer taskId) {
        List<BaseCourse> baseCourse = yunBasicService.getBaseCourse(schoolId);
        List<PlanTeachingCourse> list = planTeachingCourseService.lambdaQuery().eq(PlanTeachingCourse::getTaskId, taskId).list();
        Set<String> collect1 = list.stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toSet());

        List<BaseCourse> collect2 = baseCourse.stream().filter(a1 -> !collect1.contains(a1.getCourseNO())).collect(Collectors.toList());
        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
        collect2.forEach(a -> {
//            Course one = courseService.lambdaQuery().eq(Course::getBaseCourseId, a.getCourseNO()).eq(Course::getTaskId, taskId).one();
            Course one = courseList.stream().filter(o -> o.getBaseCourseId().equals(a.getCourseNO())).findFirst().orElse(null);
            if (one != null) {
                a.setCourseId(one.getCourseId());
            }
        });
        //获取已存在的自选教学班
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).eq(TeachingClass::getIsOptional, 1).list();
        List<Long> selfCourseIds = teachingClassList.stream().map(TeachingClass::getCourseId).collect(Collectors.toList());
        //已生成的课程不能在本学期的轮次中再次选择
        if (CollUtil.isNotEmpty(selfCourseIds)) {
            collect2 = collect2.stream().filter(a -> !selfCourseIds.contains(a.getCourseId())).collect(Collectors.toList());
        }
        return collect2;
    }

    @Override
    public ResultDto<TeachingClassDto> getTeachingClassListSelf(Integer pageSize, Integer currentPage, Integer taskId, Integer courseId) {
        ResultDto<TeachingClassDto> result = new ResultDto<>();
        //1.通过teaching_class表中的is_optional字段查询自学的教学班
        List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getTaskId, taskId)
                .eq(TeachingClass::getCourseId, courseId)
                .eq(TeachingClass::getIsOptional, 1).list();
        List<TeachingClassTeacher> teachingClassTeacherList = teachingClassTeacherService.lambdaQuery().list();
        List<TeachingClassDto> teachingClassDtoList = new ArrayList<>();
        for (TeachingClass item : teachingClasses
        ) {
            //通过教学班id查找教学班教师表得到对应的teacher_id,再通过teacher_id到teacher表中找到对应的教师信息
            TeachingClassDto view = new TeachingClassDto();
            BeanUtils.copyProperties(item, view);
//                teachingClassDtoList.add(view);
            List<TeachingClassDto.TeacherDto> teacherDtoList = new ArrayList<>();
            List<Long> teacherIds = teachingClassTeacherList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).collect(Collectors.toList())
                    .stream().map(TeachingClassTeacher::getTeacherId).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(teacherIds)) {
                List<TeacherSelfDto> teacherSelfDtoList = teacherMapper.getTeacherByIds(teacherIds);
                teacherSelfDtoList.forEach(a -> {
                    TeachingClassDto.TeacherDto teacherDto = new TeachingClassDto.TeacherDto();
                    teacherDto.setImageUrl(a.getImageUrl());
                    teacherDto.setBaseTeacherId(a.getBaseTeacherId());
                    if (a.getIdentity() == 1) {
                        //任课老师
                        teacherDto.setTeacherId(a.getTeacherId());
                        teacherDto.setTeacherName(a.getTeacherName());
                        teacherDto.setIdentity(1);
                    } else {
                        //助教老师
                        teacherDto.setAssistantId(a.getTeacherId());
                        teacherDto.setAssistantName(a.getTeacherName());
                        teacherDto.setIdentity(2);
                    }
                    teacherDtoList.add(teacherDto);
                });
            }
            view.setTeacherDtoList(teacherDtoList);
            teachingClassDtoList.add(view);
        }
        result.setList(teachingClassDtoList);
        result.setTotal((long) teachingClasses.size());

        return result;
    }

    /**
     * 清空教学班
     *
     * @param teachingClassIds
     * @param taskId
     * @return
     */
    @Override
    public Boolean clearTeachingClassSelf(List<Long> teachingClassIds, Integer taskId) {
        Integer num = teachingClassService.deleteClass(teachingClassIds);
        return num == teachingClassIds.size();
    }

    @Override
    public TeachingClassSelfDto setTeachingClassSelf(Integer courseId, String courseName, Integer total, Long roundId, String uuidForOption, Integer type, Integer sum, Integer capacity, Integer taskId) {
        TeachingClassSelfDto teachingClassSelfDto = new TeachingClassSelfDto();
        List<TeachingClass> teachingClasses = new ArrayList<>();

        //先根据课程id查找教学班表，清空原先生成的教学班
        if (roundId == null) {
            if (StringUtils.isBlank(uuidForOption)) {
                throw new BizException("自选教学班唯一标识不能为空");
            }
            teachingClassService.lambdaUpdate()
                    .eq(TeachingClass::getTaskId, taskId)
                    .eq(TeachingClass::getCourseId, courseId)
                    .eq(TeachingClass::getIsOptional, 1)
                    .eq(TeachingClass::getStudentCampus, uuidForOption)
                    .remove();
        } else {
            teachingClassService.lambdaUpdate()
                    .eq(TeachingClass::getTaskId, taskId)
                    .eq(TeachingClass::getCourseId, courseId)
                    .eq(TeachingClass::getIsOptional, 1)
                    .eq(TeachingClass::getStudentCampus, roundId.toString())
                    .remove();
        }
        List<Campus> list = campusService.lambdaQuery().eq(Campus::getTaskId, taskId).list();
        Integer campusId = null;
        String campusName = null;
        if (CollUtil.isNotEmpty(list)) {
            campusId = list.get(0).getCampusId();
            campusName = list.get(0).getCampusName();
        }

        Optional<Course> optionalCourse = courseService.lambdaQuery().eq(Course::getTaskId, taskId).eq(Course::getCourseId, courseId).list().stream().findFirst();
        if (optionalCourse.isPresent()) {
            Course course = optionalCourse.get();
            if (type == 1) {
                //按班级容量分配学生
                int numClasses = (int) Math.ceil(total / capacity);//向上取整
                if (total % capacity != 0) {
                    numClasses += 1;
                }
                for (int i = 1; i <= numClasses; i++) {
                    TeachingClass teachingClass = new TeachingClass();
                    teachingClass.setClassNum(capacity);
                    teachingClass.setTaskId(taskId);
                    teachingClass.setTeachingClassName(courseName + "(" + i + ")");
                    teachingClass.setCourseId(Long.valueOf(courseId));
                    teachingClass.setCourseName(courseName);
                    teachingClass.setTeachingClassType(1);
                    teachingClass.setCampusId(campusId);
                    teachingClass.setCampusName(campusName);
                    teachingClass.setIsOptional(1);
                    teachingClass.setFlag(1);
                    teachingClass.setMajorProp(course.getMajorProp());
                    teachingClass.setStudyNature(course.getCourseNature());
                    teachingClass.setBaseCollegeId(course.getBaseCollegeId());
                    teachingClass.setCollegeName(course.getCollegeName());
                    teachingClass.setStudentCampus(roundId == null ? uuidForOption : roundId.toString());
                    teachingClasses.add(teachingClass);
                }
            } else {
                //按班级数量分配学生
                int studentPerClass = (int) Math.ceil(total / sum);//向下取整
                if (total % sum != 0) {
                    studentPerClass += 1;
                }
                for (int i = 1; i <= sum; i++) {
                    TeachingClass teachingClass = new TeachingClass();
                    teachingClass.setClassNum(studentPerClass);
                    teachingClass.setTaskId(taskId);
                    teachingClass.setTeachingClassName(courseName + "(" + i + ")");
                    teachingClass.setCourseId(Long.valueOf(courseId));
                    teachingClass.setCourseName(courseName);
                    teachingClass.setTeachingClassType(1);
                    teachingClass.setCampusId(campusId);
                    teachingClass.setCampusName(campusName);
                    teachingClass.setIsOptional(1);
                    teachingClass.setFlag(1);
                    teachingClass.setMajorProp(course.getMajorProp());
                    teachingClass.setStudyNature(course.getCourseNature());
                    teachingClass.setBaseCollegeId(course.getBaseCollegeId());
                    teachingClass.setCollegeName(course.getCollegeName());
                    teachingClass.setStudentCampus(roundId == null ? uuidForOption : roundId.toString());
                    teachingClasses.add(teachingClass);
                }
            }
        } else {
            throw new BizException("课程不存在");
        }
        teachingClassService.saveBatch(teachingClasses);
        teachingClassSelfDto.setTeachingClasses(teachingClasses);
        teachingClassSelfDto.setTotal(teachingClasses.size());
        return teachingClassSelfDto;
    }

    @Override
    public CourseSelectionDto getCourseSelectionSelf(Integer roundId, Integer taskId) {
        CourseSelectionDto courseSelectionDto = new CourseSelectionDto();
        List<CourseSelectionDto.CourseSelectionTT> courseSelectionTTS = new ArrayList<>();
        //判断roundId存不存在
        if (roundId != null) {
            //根据轮次id获取课程
            List<CourseSelection> list = courseSelectionService.lambdaQuery().eq(CourseSelection::getRoundId, roundId).list();
            if (CollUtil.isNotEmpty(list)) {
                //以课程id进行分组
                Map<Long, List<CourseSelection>> integerListMap = list.stream().collect(Collectors.groupingBy(CourseSelection::getCourseId));
                //遍历分组后的map
                for (Map.Entry<Long, List<CourseSelection>> entry : integerListMap.entrySet()) {
                    Long courseId = entry.getKey();
                    List<CourseSelection> courseSelections = entry.getValue();

                    // 创建 CourseSelectionTT 对象
                    CourseSelectionDto.CourseSelectionTT courseSelectionTT = new CourseSelectionDto.CourseSelectionTT();
                    courseSelectionTT.setCourseId(courseId);
                    courseSelectionTT.setCourseName(courseSelections.get(0).getCourseName());

                    Course one = courseService.lambdaQuery().eq(Course::getCourseId, courseId).one();
                    if (one != null) {
                        courseSelectionTT.setCourseCode(one.getCourseCode());
                    }

                    //获取教学班数量
                    //方式:通过课程id和taskid
                    List<TeachingClass> list1 = teachingClassService.lambdaQuery().eq(TeachingClass::getCourseId, courseId).eq(TeachingClass::getTaskId, taskId).list();
                    courseSelectionTT.setTeachingClassNum(list1.size());

                    //选课总人数
                    AtomicReference<Integer> total = new AtomicReference<>(0);
                    // 创建 CourseSelectionMM 对象列表
                    List<CourseSelectionDto.CourseSelectionTT.CourseSelectionMM> courseSelectionMMS = courseSelections.stream()
                            .map(courseSelection -> {
                                CourseSelectionDto.CourseSelectionTT.CourseSelectionMM courseSelectionMM = new CourseSelectionDto.CourseSelectionTT.CourseSelectionMM();
                                courseSelectionMM.setBaseCollegeId(courseSelection.getBaseCollegeId());
                                courseSelectionMM.setBaseCollegeName(courseSelection.getBaseCollegeName());
                                courseSelectionMM.setGradeId(courseSelection.getGradeId());
                                courseSelectionMM.setGradeName(courseSelection.getGradeName());

                                //选课人数
                                //通过学院id和年级id去统计学生表
                                List<Student> list2 = studentService.lambdaQuery().eq(Student::getTaskId, taskId).eq(Student::getBaseCollegeId, courseSelectionMM.getBaseCollegeId()).eq(Student::getGradeId, courseSelectionMM.getGradeId()).list();
                                courseSelectionMM.setSum(list2.size());
                                total.updateAndGet(v -> v + list2.size());
                                return courseSelectionMM;
                            })
                            .collect(Collectors.toList());
                    courseSelectionTT.setTotal(total.get());
                    courseSelectionTT.setCourseSelectionMMS(courseSelectionMMS);
                    courseSelectionTTS.add(courseSelectionTT);
                }
            }
            //课程总数
            courseSelectionDto.setCourseNumber(list.size());
            courseSelectionDto.setCourseSelectionTTS(courseSelectionTTS);
        }
        return courseSelectionDto;
    }

    @Override
    public ResultDto<StudentInfoDto> getStudentInfoList(String baseCollegeId, String gradeId, String
            classId, String keyword, Integer pageSize, Integer currentPage, Integer taskId) {

        ResultDto<StudentInfoDto> resultDto = new ResultDto<>();

        List<StudentInfoDto> studentInfoDtos = new ArrayList<>();

        List<Student> studentList = studentService.lambdaQuery().eq(Student::getTaskId, taskId).eq(StringUtils.isNotBlank(baseCollegeId), Student::getBaseCollegeId, baseCollegeId)
                .eq(StringUtils.isNotBlank(gradeId), Student::getGradeId, gradeId)
                .eq(StringUtils.isNotBlank(classId), Student::getClassId, classId)
                .like(StringUtils.isNotBlank(keyword), Student::getStudentName, keyword).list();

        Map<String, Course> courseMap = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list().stream().collect(Collectors.toMap(Course::getBaseCourseId, Function.identity()));

        List<StudentRetake> studentRetakes = studentRetakeService.lambdaQuery().eq(StudentRetake::getTaskId, taskId).list();

        if (CollUtil.isNotEmpty(studentRetakes)) {
            List<String> baseStudentIds = studentRetakes.stream().map(StudentRetake::getBaseStudentId).collect(Collectors.toList());

            List<Student> studentRetake = studentList.stream().filter(p -> baseStudentIds.contains(p.getBaseStudentId())).collect(Collectors.toList());


            if (CollUtil.isNotEmpty(studentRetake)) {
                Map<String, Student> studentMap = studentRetake.stream().collect(Collectors.toMap(Student::getBaseStudentId, Function.identity()));

                studentRetakes.forEach(o -> {
                    if (ObjUtil.isNotNull(studentMap.get(o.getBaseStudentId()))) {
                        StudentInfoDto studentInfoDto = new StudentInfoDto();
                        studentInfoDto.setStudentName(studentMap.get(o.getBaseStudentId()).getStudentName() + "(" + o.getBaseStudentId() + ")");
                        studentInfoDto.setCourseName(ObjUtil.isNull(courseMap.get(o.getBaseCourseId())) ? "课程库未同步该课程" : courseMap.get(o.getBaseCourseId()).getCourseName() + "(" + o.getBaseCourseId() + ")");
                        studentInfoDto.setClassName(studentMap.get(o.getBaseStudentId()).getClassName());
                        studentInfoDto.setGradeNamed(studentMap.get(o.getBaseStudentId()).getGradeName());
                        studentInfoDto.setCollegeName(studentMap.get(o.getBaseStudentId()).getCollegeName());
                        studentInfoDtos.add(studentInfoDto);
                    }
                });


                List<StudentInfoDto> studentInfoDtos1 = studentInfoDtos.stream()
                        .sorted(Comparator.comparing(StudentInfoDto::getStudentName))
                        .skip((long) (currentPage - 1) * pageSize)
                        .limit(pageSize)
                        .collect(Collectors.toList());


                resultDto.setCurrentPage(currentPage);
                resultDto.setPageSize(pageSize);
                resultDto.setList(studentInfoDtos1);
                resultDto.setTotal((long) studentInfoDtos.size());
            }
        } else {
            resultDto.setCurrentPage(currentPage);
            resultDto.setPageSize(pageSize);
            resultDto.setList(new ArrayList<>());
            resultDto.setTotal((long) studentInfoDtos.size());
        }

        return resultDto;

    }


    @Override
    public ResultDto<StudentSelectInfoDto> getStudentSelectList(String baseCollegeId, String gradeId, String classId, String keyword, Integer pageSize, Integer currentPage, Integer taskId, Integer needToSelect, Integer flag, Integer roundId) {

        ResultDto<StudentSelectInfoDto> resultDto = new ResultDto<>();
        List<StudentSelectInfoDto> studentSelectInfoDtos = new ArrayList<>();
        List<Student> studentList = studentService.lambdaQuery().eq(Student::getTaskId, taskId).list();
        List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).list();
        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
        List<MajorGrade> majorGradeList = majorGradeService.lambdaQuery().eq(MajorGrade::getTaskId, taskId).list();
        CssTaskRound round = cssTaskRoundService.getById(roundId);
        //重修相关逻辑
        if (flag == 1) {
            List<StudentRetake> studentRetakes = studentRetakeService.lambdaQuery().eq(StudentRetake::getTaskId, taskId).list();
            if (CollUtil.isNotEmpty(studentRetakes)) {
                Map<String, List<StudentRetake>> studentRetakeMap = studentRetakes.stream().collect(Collectors.groupingBy(StudentRetake::getBaseStudentId));


                studentRetakeMap.forEach((key, value) -> {
                    StudentSelectInfoDto studentSelectInfoDto = new StudentSelectInfoDto();
                    Student student = studentList.stream().filter(p -> p.getBaseStudentId().equals(key)).findFirst().orElse(null);
                    if (ObjUtil.isNotNull(student)) {

                        studentSelectInfoDto.setStudentId(student.getStudentId());
                        studentSelectInfoDto.setStudentName(student.getStudentName());
                        studentSelectInfoDto.setCollegeName(student.getCollegeName());
                        studentSelectInfoDto.setGradeName(student.getGradeName());
                        studentSelectInfoDto.setClassName(student.getClassName());
                        studentSelectInfoDto.setImageUrl(student.getImageUrl());
                        studentSelectInfoDto.setBaseStudentId(student.getBaseStudentId());

                        Optional<MajorGrade> optionalMajorGrade = majorGradeList.stream().filter(a -> a.getGradeId().equals(student.getGradeId())
                                && a.getBaseMajorId().equals(student.getMajorId())
                                && a.getBaseCollegeId().equals(student.getBaseCollegeId())).findFirst();
                        if (optionalMajorGrade.isPresent()) {
                            MajorGrade majorGrade = optionalMajorGrade.get();
                            studentSelectInfoDto.setCampusId(majorGrade.getCampusId());
                            studentSelectInfoDto.setCampusName(majorGrade.getCampusName());
                        }


                        List<TeachingClass> teachingClassList = new ArrayList<>();

                        List<TeachingClass> selectTeachingClassList = teachingClasses.stream().filter(p -> p.getTeachingClassType().equals(2) || p.getTeachingClassType().equals(4)).collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(selectTeachingClassList)) {
                            List<TeachingClassStudent> teachingClassStudents = teachingClassStudentService.lambdaQuery().eq(TeachingClassStudent::getStudentId, student.getStudentId()).eq(TeachingClassStudent::getFlag, 1).list();
                            if (CollUtil.isNotEmpty(teachingClassStudents)) {
                                List<Long> teachingClassIds = teachingClassStudents.stream().map(TeachingClassStudent::getTeachingClassId).distinct().collect(Collectors.toList());
                                teachingClassList = selectTeachingClassList.stream().filter(p -> teachingClassIds.contains(p.getTeachingClassId())).collect(Collectors.toList());
                                studentSelectInfoDto.setTeachingClassList(teachingClassList);
                            }
                        }


                        List<String> baseCourseIds = value.stream().map(StudentRetake::getBaseCourseId).collect(Collectors.toList());

                        List<Course> courses = courseList.stream().filter(p -> baseCourseIds.contains(p.getBaseCourseId())).collect(Collectors.toList());


                        studentSelectInfoDto.setCourseList(courses);

                        studentSelectInfoDto.setNeedNum(courses.size());

                        studentSelectInfoDto.setSelectNum(teachingClassList.size());

                        studentSelectInfoDtos.add(studentSelectInfoDto);
                    }
                });

                List<StudentSelectInfoDto> studentInfoDtos1 = studentSelectInfoDtos.stream()
                        .sorted(Comparator.comparing(StudentSelectInfoDto::getStudentName))
                        .skip((long) (currentPage - 1) * pageSize)
                        .limit(pageSize)
                        .collect(Collectors.toList());

                resultDto.setCurrentPage(currentPage);
                resultDto.setPageSize(pageSize);
                resultDto.setList(studentInfoDtos1);
                resultDto.setTotal((long) studentSelectInfoDtos.size());

            } else {
                resultDto.setCurrentPage(currentPage);
                resultDto.setPageSize(pageSize);
                resultDto.setList(new ArrayList<>());
                resultDto.setTotal((long) studentSelectInfoDtos.size());
            }


        } else if (flag == 0) {
            List<StudentSelectInfoDto> studentInfos = new ArrayList<>();
            //获取轮次对应学生范围
            List<CssStudentRange> cssStudentRangeList = cssStudentRangeService.lambdaQuery()
                    .eq(CssStudentRange::getRoundId, roundId)
                    .eq(StringUtils.isNotBlank(baseCollegeId), CssStudentRange::getBaseCollegeId, baseCollegeId)
                    .eq(StringUtils.isNotBlank(gradeId), CssStudentRange::getGradeId, gradeId)
                    .list();
            //获取学生
            List<Student> students = new ArrayList<>();
            for (CssStudentRange studentRange : cssStudentRangeList) {
                List<Student> studentTemp = studentList.stream().filter(a ->
                                a.getGradeId().equals(studentRange.getGradeId()) && a.getBaseCollegeId().equals(studentRange.getBaseCollegeId()))
                        .collect(Collectors.toList());
                students.addAll(studentTemp);
            }
            if (StringUtils.isNotBlank(classId)) {
                students = students.stream().filter(a -> a.getClassId().equals(classId)).collect(Collectors.toList());
            }
            //获取所有培养方案
            List<PlanTeachingStudent> planTeachingStudents = planTeachingStudentService.lambdaQuery().eq(PlanTeachingStudent::getTaskId, taskId).list();

            List<CssRoundCourse> roundCourses = cssRoundCourseService.lambdaQuery().eq(CssRoundCourse::getRoundId, roundId).eq(CssRoundCourse::getTaskId, taskId).list();
            List<Long> courseIds = roundCourses.stream().map(CssRoundCourse::getCourseId).collect(Collectors.toList());
            if (CollUtil.isEmpty(courseIds)) {
                throw new BizException("本轮次没有选课课程");
            }
            List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery()
                    .eq(TeachingClass::getIsOptional, 0)
                    .eq(TeachingClass::getTaskId, taskId)
                    .in(TeachingClass::getCourseId, courseIds)
                    .list();
            List<Long> idCollect = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            //获取所有选课学生
            if (CollUtil.isEmpty(idCollect)) {
                return resultDto;
            }
            List<TeachingClassStudent> teachingClassStudents = teachingClassStudentService.lambdaQuery().eq(TeachingClassStudent::getFlag, 1)
                    .in(TeachingClassStudent::getTeachingClassId, idCollect).list();
            if (round != null && round.getSelectType().equals(2)) {
                Date currentTime = new Date();
                if (currentTime.after(round.getBeginTime()) && currentTime.before(round.getEndTime()) && round.getIsEnable().equals(1)) {
                    List<TeachingClassStudent> selectDataByRedis = this.getSelectDataByRedis(taskId, teachingClassList);
                    for (TeachingClassStudent redisClass : selectDataByRedis) {
                        //因为redis之前轮次选课数据不进行删除，所以仅当数据库不存在时添加为返回值
                        boolean isExist = teachingClassStudents.stream().anyMatch(a -> a.getTeachingClassId().equals(redisClass.getTeachingClassId()) && a.getStudentId().equals(redisClass.getStudentId()));
                        if (!isExist) {
                            teachingClassStudents.add(redisClass);
                        }
                    }
                }
            }

            List<PlanTeachingCourse> allPlanTeachingCourses = planTeachingCourseService.lambdaQuery().eq(PlanTeachingCourse::getTaskId, taskId).list();
            //数据处理
            for (Student student : students) {
                StudentSelectInfoDto view = new StudentSelectInfoDto();
                view.setStudentId(student.getStudentId());
                view.setStudentName(student.getStudentName());
                view.setCollegeName(student.getCollegeName());
                view.setGradeName(student.getGradeName());
                view.setClassName(student.getClassName());
                view.setImageUrl(student.getImageUrl());
                view.setBaseStudentId(student.getBaseStudentId());
                Optional<MajorGrade> optionalMajorGrade = majorGradeList.stream().filter(a -> a.getGradeId().equals(student.getGradeId())
                        && a.getBaseMajorId().equals(student.getMajorId())
                        && a.getBaseCollegeId().equals(student.getBaseCollegeId())).findFirst();
                if (optionalMajorGrade.isPresent()) {
                    MajorGrade majorGrade = optionalMajorGrade.get();
                    view.setCampusId(majorGrade.getCampusId());
                    view.setCampusName(majorGrade.getCampusName());
                }
                Optional<PlanTeachingStudent> optionalPlanTeachingStudent = planTeachingStudents.stream().filter(a -> a.getBaseStudentId().equals(student.getBaseStudentId())).findFirst();
                if (optionalPlanTeachingStudent.isPresent()) {
                    PlanTeachingStudent planTeachingStudent = optionalPlanTeachingStudent.get();
                    List<PlanTeachingCourse> planTeachingCourses = allPlanTeachingCourses.stream().filter(a -> a.getBaseTeachingPlanId().equals(planTeachingStudent.getBaseTeachingPlanId())).collect(Collectors.toList());
                    List<String> baseCourseIds = planTeachingCourses.stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toList());
                    List<Long> planCourseIds = courseList.stream().filter(a -> baseCourseIds.contains(a.getBaseCourseId())).map(Course::getCourseId).collect(Collectors.toList());
                    //应选课程
                    List<Long> courseIdsNeed = cssSelectCourseService.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId)
                            .in(CssSelectCourse::getCourseId, planCourseIds).list()
                            .stream().map(CssSelectCourse::getCourseId).collect(Collectors.toList());
                    view.setNeedNum(courseIdsNeed.size());
                }
                List<TeachingClassStudent> classStudents = teachingClassStudents.stream().filter(a -> a.getStudentId().equals(student.getStudentId())).collect(Collectors.toList());
                view.setSelectNum(classStudents.size());
                studentInfos.add(view);
                if (needToSelect == 1 && Objects.equals(view.getSelectNum(), view.getNeedNum())) {
                    studentInfos.remove(view);
                }
            }
            if (StringUtils.isNotBlank(keyword)) {
                studentInfos = studentInfos.stream().filter(a -> a.getStudentName().contains(keyword) || a.getBaseStudentId().contains(keyword)).collect(Collectors.toList());
            }
            studentInfos = studentInfos.stream().filter(a -> a.getNeedNum() != 0).collect(Collectors.toList());
            resultDto.setTotal((long) studentInfos.size());
            resultDto.setPages((long) (studentInfos.size() % pageSize == 0 ? studentInfos.size() / pageSize : studentInfos.size() / pageSize + 1));
            studentInfos = studentInfos.stream()
                    .sorted(Comparator.comparing(StudentSelectInfoDto::getStudentName))
                    .skip((long) (currentPage - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
            resultDto.setCurrentPage(currentPage);
            resultDto.setPageSize(pageSize);
            resultDto.setList(studentInfos);
        } else if (flag == 2) {
            List<StudentSelectInfoDto> studentInfos = new ArrayList<>();
            //获取轮次对应学生范围
            List<CourseSelection> courseSelectionList = courseSelectionService.lambdaQuery().eq(CourseSelection::getRoundId, roundId).list();
            List<Long> courseIds = courseSelectionList.stream().map(CourseSelection::getCourseId).collect(Collectors.toList());
            if (CollUtil.isEmpty(courseIds)) {
                return resultDto;
            }
            //获取学生（根据前端传入筛选）
            List<Student> optionalStudentList = studentService.lambdaQuery().eq(Student::getTaskId, taskId)
                    .eq(StringUtils.isNotBlank(baseCollegeId), Student::getBaseCollegeId, baseCollegeId)
                    .eq(StringUtils.isNotBlank(gradeId), Student::getGradeId, gradeId)
                    .eq(StringUtils.isNotBlank(classId), Student::getClassId, classId)
                    .like(StringUtils.isNotBlank(keyword), Student::getStudentName, keyword).list();
            List<Student> students = new ArrayList<>();
            for (CourseSelection courseSelection : courseSelectionList) {
                List<Student> studentTemp = optionalStudentList.stream().filter(a -> a.getGradeId().equals(courseSelection.getGradeId())
                                && a.getBaseCollegeId().equals(courseSelection.getBaseCollegeId()))
                        .collect(Collectors.toList());
                students.addAll(studentTemp);
            }
            students = students.stream().distinct().collect(Collectors.toList());
            //获取所有选课学生
            List<TeachingClassStudent> teachingClassStudents = teachingClassStudentService.lambdaQuery().eq(TeachingClassStudent::getFlag, 1).list();
            List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery()
                    .eq(TeachingClass::getIsOptional, 1)
                    .eq(TeachingClass::getTaskId, taskId)
                    .in(TeachingClass::getCourseId, courseIds)
                    .list();
            if (round != null && round.getSelectType().equals(4)) {
                Date currentTime = new Date();
                if (currentTime.after(round.getBeginTime()) && currentTime.before(round.getEndTime()) && round.getIsEnable().equals(1)) {
                    List<TeachingClassStudent> selectDataByRedis = this.getSelectDataByRedis(taskId, teachingClassList);
                    for (TeachingClassStudent redisClass : selectDataByRedis) {
                        //因为redis之前轮次选课数据不进行删除，所以仅当数据库不存在时添加为返回值
                        boolean isExist = teachingClassStudents.stream().anyMatch(a -> a.getTeachingClassId().equals(redisClass.getTeachingClassId()) && a.getStudentId().equals(redisClass.getStudentId()));
                        if (!isExist) {
                            teachingClassStudents.add(redisClass);
                        }
                    }
                }
            }
            //本轮次对应的教学班
            List<TeachingClass> roundWithClass = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).eq(TeachingClass::getStudentCampus, roundId.toString()).list();
            List<Long> roundWithIds = roundWithClass.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            teachingClassStudents = teachingClassStudents.stream().filter(a -> roundWithIds.contains(a.getTeachingClassId())).collect(Collectors.toList());

            //数据处理
            for (Student student : students) {
                StudentSelectInfoDto view = new StudentSelectInfoDto();
                view.setStudentId(student.getStudentId());
                view.setStudentName(student.getStudentName());
                view.setCollegeName(student.getCollegeName());
                view.setGradeName(student.getGradeName());
                view.setClassName(student.getClassName());
                view.setImageUrl(student.getImageUrl());
                view.setBaseStudentId(student.getBaseStudentId());
                Optional<MajorGrade> optionalMajorGrade = majorGradeList.stream().filter(a -> a.getGradeId().equals(student.getGradeId())
                        && a.getBaseMajorId().equals(student.getMajorId())
                        && a.getBaseCollegeId().equals(student.getBaseCollegeId())).findFirst();
                if (optionalMajorGrade.isPresent()) {
                    MajorGrade majorGrade = optionalMajorGrade.get();
                    view.setCampusId(majorGrade.getCampusId());
                    view.setCampusName(majorGrade.getCampusName());
                }
                view.setNeedNum(student.getCourseLimit() == null ? 0 : student.getCourseLimit());
                List<TeachingClassStudent> classStudents = teachingClassStudents.stream().filter(a -> a.getStudentId().equals(student.getStudentId())).collect(Collectors.toList());
                view.setSelectNum(classStudents.size());
                studentInfos.add(view);
                if (needToSelect == 1 && view.getNeedNum() <= view.getSelectNum()) {
                    studentInfos.remove(view);
                }
            }

            resultDto.setTotal((long) studentInfos.size());
            resultDto.setPages((long) (studentInfos.size() % pageSize == 0 ? studentInfos.size() / pageSize : studentInfos.size() / pageSize + 1));
            studentInfos = studentInfos.stream()
                    .sorted(Comparator.comparing(StudentSelectInfoDto::getStudentName))
                    .skip((long) (currentPage - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
            resultDto.setCurrentPage(currentPage);
            resultDto.setPageSize(pageSize);
            resultDto.setList(studentInfos);
        }
        return resultDto;
    }


    @Override
    public AccessSelectedStudentDto accessSelectedStudents(Long studentId, Integer pageSize, Integer currentPage, Integer taskId, Integer flag, Integer roundId) {
        AccessSelectedStudentDto accessSelectedStudentDto = new AccessSelectedStudentDto();
        List<Student> studentList = studentService.lambdaQuery().eq(Student::getTaskId, taskId).list();
        List<Course> courses = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).ne(TeachingClass::getTeachingClassType, 0).list();
        CssTaskRound round = cssTaskRoundService.getById(roundId);
//        Student student = studentList.stream().filter(p -> p.getStudentId().equals(studentId)).findFirst().orElse(null);
        Student student = studentService.getById(studentId);
        if (flag == 1) {
            if (ObjUtil.isNotNull(student)) {
                List<StudentRetake> studentRetakes = studentRetakeService.lambdaQuery().eq(StudentRetake::getTaskId, taskId).eq(StudentRetake::getBaseStudentId, student.getBaseStudentId()).list();

                if (CollUtil.isNotEmpty(studentRetakes)) {

                    List<String> baseCourseIds = studentRetakes.stream().map(StudentRetake::getBaseCourseId).collect(Collectors.toList());

                    List<TeachingClass> teachingClasses = teachingClassList.stream().filter(p -> p.getTeachingClassType().equals(2) || p.getTeachingClassType().equals(4)).collect(Collectors.toList());

                    if (CollUtil.isNotEmpty(teachingClasses)) {

                        List<TeachingClassStudent> teachingClassStudents = teachingClassStudentService.lambdaQuery().eq(TeachingClassStudent::getStudentId, student.getStudentId()).eq(TeachingClassStudent::getFlag, 1).list();

                        List<Long> teachingClassIds = teachingClassStudents.stream().map(TeachingClassStudent::getTeachingClassId).distinct().collect(Collectors.toList());

                        if (CollUtil.isNotEmpty(teachingClassIds)) {

                            List<TeachingClass> teachingClasses1 = teachingClasses.stream().filter(p -> teachingClassIds.contains(p.getTeachingClassId())).collect(Collectors.toList());

                            teachingClasses1.forEach(o -> {

                                List<TeachingClassStudent> list = teachingClassStudentService.lambdaQuery().eq(TeachingClassStudent::getTeachingClassId, o.getTeachingClassId()).eq(TeachingClassStudent::getFlag, 1).list();

                                List<Long> studentIds = list.stream().map(TeachingClassStudent::getStudentId).collect(Collectors.toList());

                                o.setStudentIds(studentIds);

                                List<TeachingClassWeek> teachingClassWeeks = teachingClassWeekService.lambdaQuery().eq(TeachingClassWeek::getTeachingClassId, o.getTeachingClassId()).list();

                                o.setTeachingClassWeeks(teachingClassWeeks);

                                List<TeachingClassTeacher> teachingClassTeachers = teachingClassTeacherService.lambdaQuery().eq(TeachingClassTeacher::getTeachingClassId, o.getTeachingClassId()).list();

                                o.setTeachingClassTeachers(teachingClassTeachers);
                            });

                            List<Course> courseList = courses.stream().filter(p -> baseCourseIds.contains(p.getBaseCourseId())).collect(Collectors.toList());

                            List<Long> courseIds = courseList.stream().map(Course::getCourseId).collect(Collectors.toList());

                            List<TeachingClass> teachingClasses2 = teachingClasses1.stream().filter(p -> courseIds.contains(p.getCourseId())).collect(Collectors.toList());

                            List<Long> courseId = teachingClasses2.stream().map(TeachingClass::getCourseId).collect(Collectors.toList());

                            accessSelectedStudentDto.setTeachingClassList(teachingClasses2);

                            List<Course> collect = courseList.stream().filter(p -> !courseId.contains(p.getCourseId())).collect(Collectors.toList());

                            accessSelectedStudentDto.setCourseList(collect);
                        }
                    }
                }
            }
        } else if (flag == 0) {
            //获取所有老师
            List<Teacher> teachers = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId).list();
            //获取选课学生
            List<TeachingClassStudent> teachingClassStudentList = teachingClassStudentService.lambdaQuery().eq(TeachingClassStudent::getStudentId, studentId).eq(TeachingClassStudent::getFlag, 1).list();
            //获取选课教学班id
            List<Long> teachingClassIds = teachingClassStudentList.stream().map(TeachingClassStudent::getTeachingClassId).collect(Collectors.toList());
            List<TeachingClassStudent> teachingClassStudents = new ArrayList<>();
            List<TeachingClassTeacher> teachingClassTeachers = new ArrayList<>();
            if (CollUtil.isNotEmpty(teachingClassIds)) {
                //获取所有教学班学生
                teachingClassStudents = teachingClassStudentService.lambdaQuery().in(TeachingClassStudent::getTeachingClassId, teachingClassIds).eq(TeachingClassStudent::getFlag, 1).list();
                //获取所有教学班教师
                teachingClassTeachers = teachingClassTeacherService.lambdaQuery().in(TeachingClassTeacher::getTeachingClassId, teachingClassIds).list();
            }
            //获取选课条件
            List<CssTaskInfo> cssTaskInfos = cssTaskInfoService.lambdaQuery().eq(CssTaskInfo::getTaskId, taskId).eq(CssTaskInfo::getType, 2).list();
            if (CollUtil.isEmpty(cssTaskInfos)) {
                throw new BizException("请先完成选课条件设置");
            }
            CssTaskInfo cssTaskInfo = cssTaskInfos.get(0);
            //获取选课教学班
            List<TeachingClass> teachingClasses = teachingClassList.stream().filter(a -> teachingClassIds.contains(a.getTeachingClassId())).collect(Collectors.toList());
            for (TeachingClass teachingClass : teachingClasses) {
                teachingClass.setLimitClassNum(cssTaskInfo.getClassNum());
                //填充教学班学生数据
                List<Long> studentIds = teachingClassStudents.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .map(TeachingClassStudent::getStudentId)
                        .collect(Collectors.toList());
                teachingClass.setStudentIds(studentIds);
                //填充教学班教师数据
                List<TeachingClassTeacher> teachingClassTeacherList = teachingClassTeachers.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .collect(Collectors.toList());
                teachingClassTeacherList.forEach(t -> {
                    Optional<Teacher> optionalTeacher = teachers.stream().filter(p -> p.getTeacherId().equals(t.getTeacherId())).findFirst();
                    if (optionalTeacher.isPresent()) {
                        Teacher teacher = optionalTeacher.get();
                        t.setIdentity(teacher.getIdentity());
                        t.setImageUrl(teacher.getImageUrl());
                        t.setTeacherName(teacher.getTeacherName());
                        t.setBaseTeacherId(teacher.getBaseTeacherId());
                    }
                });
                teachingClass.setTeachingClassTeachers(teachingClassTeacherList);
            }
            accessSelectedStudentDto.setTeachingClassList(teachingClasses);

            //获取选课课程id
            List<Long> courseIds = teachingClasses.stream().map(TeachingClass::getCourseId).collect(Collectors.toList());
            //获取培养方案
            PlanTeachingStudent planTeachingStudent = planTeachingStudentService.lambdaQuery()
                    .eq(PlanTeachingStudent::getBaseStudentId, student.getBaseStudentId())
                    .eq(PlanTeachingStudent::getTaskId, taskId)
                    .one();
            //获取应选课程id
            List<PlanTeachingCourse> planTeachingCourses = planTeachingCourseService.lambdaQuery()
                    .eq(PlanTeachingCourse::getBaseTeachingPlanId, planTeachingStudent.getBaseTeachingPlanId())
                    .list();
            List<String> baseCourseIdsNeed = planTeachingCourses.stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toList());
            List<Long> planCourseIds = courses.stream().filter(a -> baseCourseIdsNeed.contains(a.getBaseCourseId())).map(Course::getCourseId).collect(Collectors.toList());
            //应选课程
            List<Long> courseIdsNeed = cssSelectCourseService.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId)
                    .in(CssSelectCourse::getCourseId, planCourseIds).list()
                    .stream().map(CssSelectCourse::getCourseId).collect(Collectors.toList());
//            List<Long> courseIdsNeed = courses.stream().filter(a -> baseCourseIdsNeed.contains(a.getBaseCourseId())).map(Course::getCourseId).collect(Collectors.toList());
            //未选课程id
            courseIdsNeed.removeAll(courseIds);
            //过滤没有教学班的课程
            List<Long> removeIds = new ArrayList<>();
            courseIdsNeed.forEach(courseId -> {
                List<TeachingClass> byCourse = courseService.getTeachingClassByCourse(taskId, courseId, 1, 2000, null, null,null).getList();
                if (CollUtil.isEmpty(byCourse)) {
                    removeIds.add(courseId);
                }
            });
            courseIdsNeed.removeAll(removeIds);
            //获取未选课程，返回数据
            List<Course> courseList = courses.stream().filter(a -> courseIdsNeed.contains(a.getCourseId())).collect(Collectors.toList());
            courseList.forEach(course -> course.setLimitClassNum(cssTaskInfo.getClassNum()));
            accessSelectedStudentDto.setCourseList(courseList);
        } else if (flag == 2) {
            //获取所有老师
            List<Teacher> teachers = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId).list();
            //获取选课学生
            List<TeachingClassStudent> teachingClassStudentList = teachingClassStudentService.lambdaQuery().eq(TeachingClassStudent::getStudentId, studentId).eq(TeachingClassStudent::getFlag, 1).list();
            if (round != null && round.getSelectType().equals(4)) {
                Date currentTime = new Date();
                if (currentTime.after(round.getBeginTime()) && currentTime.before(round.getEndTime()) && round.getIsEnable().equals(1)) {
                    List<TeachingClassStudent> selectDataByRedis = this.getSelectDataByRedis(taskId, teachingClassList);
                    selectDataByRedis = selectDataByRedis.stream().filter(a -> a.getStudentId().equals(studentId)).collect(Collectors.toList());
                    for (TeachingClassStudent redisClass : selectDataByRedis) {
                        //因为redis之前轮次选课数据不进行删除，所以仅当数据库不存在时添加为返回值
                        boolean isExist = teachingClassStudentList.stream().anyMatch(a -> a.getTeachingClassId().equals(redisClass.getTeachingClassId()) && a.getStudentId().equals(redisClass.getStudentId()));
                        if (!isExist) {
                            teachingClassStudentList.add(redisClass);
                        }
                    }
                }
            }
            //获取选课教学班id
            List<Long> teachingClassIds = teachingClassStudentList.stream().map(TeachingClassStudent::getTeachingClassId).collect(Collectors.toList());
            List<TeachingClassStudent> teachingClassStudents = new ArrayList<>();
            List<TeachingClassTeacher> teachingClassTeachers = new ArrayList<>();
            if (CollUtil.isNotEmpty(teachingClassIds)) {
                //获取所有教学班学生
                teachingClassStudents = teachingClassStudentService.lambdaQuery().in(TeachingClassStudent::getTeachingClassId, teachingClassIds).eq(TeachingClassStudent::getFlag, 1).list();
                //获取所有教学班教师
                teachingClassTeachers = teachingClassTeacherService.lambdaQuery().in(TeachingClassTeacher::getTeachingClassId, teachingClassIds).list();
            }
            //获取选课条件
            List<CssTaskInfo> cssTaskInfos = cssTaskInfoService.lambdaQuery().eq(CssTaskInfo::getTaskId, taskId).eq(CssTaskInfo::getType, 2).list();
            if (CollUtil.isEmpty(cssTaskInfos)) {
                throw new BizException("请先完成选课条件设置");
            }
            CssTaskInfo cssTaskInfo = cssTaskInfos.get(0);
            //获取选课教学班
            teachingClassList = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).eq(TeachingClass::getStudentCampus, roundId.toString()).list();
            List<TeachingClass> teachingClasses = teachingClassList.stream().filter(a -> teachingClassIds.contains(a.getTeachingClassId())).collect(Collectors.toList());
            for (TeachingClass teachingClass : teachingClasses) {
                teachingClass.setLimitClassNum(cssTaskInfo.getClassNum());
                //填充教学班学生数据
                List<Long> studentIds = teachingClassStudents.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .map(TeachingClassStudent::getStudentId)
                        .collect(Collectors.toList());
                teachingClass.setStudentIds(studentIds);
                //填充教学班教师数据
                List<TeachingClassTeacher> teachingClassTeacherList = teachingClassTeachers.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .collect(Collectors.toList());
                teachingClassTeacherList.forEach(t -> {
                    Optional<Teacher> optionalTeacher = teachers.stream().filter(p -> p.getTeacherId().equals(t.getTeacherId())).findFirst();
                    if (optionalTeacher.isPresent()) {
                        Teacher teacher = optionalTeacher.get();
                        t.setIdentity(teacher.getIdentity());
                        t.setImageUrl(teacher.getImageUrl());
                        t.setTeacherName(teacher.getTeacherName());
                        t.setBaseTeacherId(teacher.getBaseTeacherId());
                    }
                });
                teachingClass.setTeachingClassTeachers(teachingClassTeacherList);
            }
            accessSelectedStudentDto.setTeachingClassList(teachingClasses);
            accessSelectedStudentDto.setCourseList(new ArrayList<>());
//            //获取选课课程id
//            List<Long> courseIds = teachingClasses.stream().map(TeachingClass::getCourseId).collect(Collectors.toList());
//            //获取培养方案
//            PlanTeachingStudent planTeachingStudent = planTeachingStudentService.lambdaQuery()
//                    .eq(PlanTeachingStudent::getBaseStudentId, student.getBaseStudentId())
//                    .eq(PlanTeachingStudent::getTaskId, taskId)
//                    .one();
//            //获取应选课程id
//            List<PlanTeachingCourse> planTeachingCourses = planTeachingCourseService.lambdaQuery()
//                    .eq(PlanTeachingCourse::getBaseTeachingPlanId, planTeachingStudent.getBaseTeachingPlanId())
//                    .list();
//            List<String> baseCourseIdsNeed = planTeachingCourses.stream().map(PlanTeachingCourse::getBaseCourseId).collect(Collectors.toList());
//            List<Long> courseIdsNeed = courses.stream().filter(a -> baseCourseIdsNeed.contains(a.getBaseCourseId())).map(Course::getCourseId).collect(Collectors.toList());
//            //未选课程id
//            courseIdsNeed.removeAll(courseIds);
//            //过滤没有教学班的课程
//            List<Long> removeIds = new ArrayList<>();
//            courseIdsNeed.forEach(courseId -> {
//                List<TeachingClass> byCourse = courseService.getByCourse(taskId, courseId, null);
//                if (CollUtil.isEmpty(byCourse)) {
//                    removeIds.add(courseId);
//                }
//            });
//            courseIdsNeed.removeAll(removeIds);
//            //获取未选课程，返回数据
//            List<Course> courseList = courses.stream().filter(a -> courseIdsNeed.contains(a.getCourseId())).collect(Collectors.toList());
//            courseList.forEach(course -> course.setLimitClassNum(cssTaskInfo.getClassNum()));
//            accessSelectedStudentDto.setCourseList(courseList);

        }
        return accessSelectedStudentDto;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String cancelClasses(Long teachingClassId, String authorization, String userId, String userName, Integer taskId) {
        List<Long> teachingClassIds = Collections.singletonList(teachingClassId);
        yunBasicServiceImpl.sendSelectCourseCancelMsg(teachingClassIds, taskId, userId, userName, authorization);
        teachingClassService.deleteClass(teachingClassIds);
        DeleteClass deleteClass = new DeleteClass();
        deleteClass.setTeachingClassId(teachingClassId);
        deleteClass.setTaskId(taskId);
        deleteClassService.save(deleteClass);
        return "该班级已取消开班";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDto<TeachingClass> getStudentRetakeClass(String baseCollegeId, Long courseId, String keyword, Integer pageSize, Integer currentPage, Integer taskId, Integer flag, Integer roundId) {
        ResultDto<TeachingClass> resultDto = new ResultDto<>();
        List<Teacher> teacherList = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId).list();
        CssTaskRound round = cssTaskRoundService.getById(roundId);
        if (flag.equals(1)) {
            List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId)
                    .eq(StringUtils.isNotBlank(baseCollegeId), TeachingClass::getBaseCollegeId, baseCollegeId)
                    .eq(ObjUtil.isNotNull(courseId), TeachingClass::getCourseId, courseId)
                    .eq(TeachingClass::getTeachingClassType, 4).like(StringUtils.isNotBlank(keyword)
                            , TeachingClass::getTeachingClassName, keyword).list();

            if (CollUtil.isNotEmpty(teachingClassList)) {

                teachingClassList.forEach(o -> {
                    List<TeachingClassWeek> teachingClassWeekList = teachingClassWeekService.lambdaQuery().eq(TeachingClassWeek::getTeachingClassId, o.getTeachingClassId()).list();
                    o.setTeachingClassWeeks(teachingClassWeekList);
                    List<TeachingClassTeacher> teachingClassTeachers = teachingClassTeacherService.lambdaQuery().eq(TeachingClassTeacher::getTeachingClassId, o.getTeachingClassId()).list();

                    o.setTeachingClassTeachers(teachingClassTeachers);

                    List<Long> studenIds = teachingClassStudentService.lambdaQuery()
                            .eq(TeachingClassStudent::getTeachingClassId, o.getTeachingClassId())
                            .eq(TeachingClassStudent::getFlag, 1).list()
                            .stream().map(TeachingClassStudent::getStudentId).collect(Collectors.toList());

                    o.setStudentIds(studenIds);
                });

                PageInfo<TeachingClass> pageInfo = PagingUtil.getPages(currentPage, pageSize, teachingClassList);
                resultDto.setCurrentPage(currentPage);
                resultDto.setPageSize(pageSize);
                resultDto.setList(pageInfo.getList());
                resultDto.setTotal(pageInfo.getTotal());
            } else {
                resultDto.setCurrentPage(currentPage);
                resultDto.setPageSize(pageSize);
                resultDto.setList(new ArrayList<>());
                resultDto.setTotal(0L);
            }
        } else if (flag == 0) {
            //获取设置的选课课程
            List<CssSelectCourse> cssSelectCourseList = cssSelectCourseService.lambdaQuery().eq(CssSelectCourse::getTaskId, taskId).list();
            List<Long> courseIds = cssSelectCourseList.stream().map(CssSelectCourse::getCourseId).collect(Collectors.toList());
            //获取教学班
            List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery()
                    .in(TeachingClass::getCourseId, courseIds)
                    .eq(TeachingClass::getTaskId, taskId)
                    .eq(StringUtils.isNotBlank(baseCollegeId), TeachingClass::getBaseCollegeId, baseCollegeId)
                    .eq(ObjUtil.isNotNull(courseId), TeachingClass::getCourseId, courseId)
                    .like(StringUtils.isNotBlank(keyword), TeachingClass::getTeachingClassName, keyword)
                    .eq(TeachingClass::getIsOptional, 0)
                    .ne(TeachingClass::getTeachingClassType, 0)
                    .isNull(TeachingClass::getUniqueShiftSign)
                    .list();
            List<Long> ids = teachingClasses.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            List<TeachingClassTeacher> classTeachers = new ArrayList<>();
            List<TeachingClassStudent> classStudents = new ArrayList<>();
            if (CollUtil.isNotEmpty(ids)) {
                //获取教学班教师
                classTeachers = teachingClassTeacherService.lambdaQuery().in(TeachingClassTeacher::getTeachingClassId, ids).list();
                //获取教学班学生
                classStudents = teachingClassStudentService.lambdaQuery().in(TeachingClassStudent::getTeachingClassId, ids).eq(TeachingClassStudent::getFlag, 1).list();
                if (round != null && round.getSelectType().equals(2)) {
                    Date currentTime = new Date();
                    if (currentTime.after(round.getBeginTime()) && currentTime.before(round.getEndTime()) && round.getIsEnable().equals(1)) {
                        List<TeachingClassStudent> redisList = this.getSelectDataByRedis(taskId, teachingClasses);
                        for (TeachingClassStudent redisClass : redisList) {
                            //因为redis之前轮次选课数据不进行删除，所以仅当数据库不存在时添加为返回值
                            boolean isExist = classStudents.stream().anyMatch(a -> a.getTeachingClassId().equals(redisClass.getTeachingClassId()) && a.getStudentId().equals(redisClass.getStudentId()));
                            if (!isExist) {
                                classStudents.add(redisClass);
                            }
                        }
                    } else {
                        studentService.saveRedisData(taskId, teachingClasses, "Online");
//                        if (round.getRound() == null || !round.getRound().equals(1)) {
//                            studentService.saveRedisData(taskId, teachingClasses);
//                            round.setRound(1);
//                            cssTaskRoundService.updateById(round);
//                        }
                    }
                }
            }

            for (TeachingClassTeacher classTeacher : classTeachers) {
                Optional<Teacher> optionalTeacher = teacherList.stream().filter(a -> a.getTeacherId().equals(classTeacher.getTeacherId())).findFirst();
                if (optionalTeacher.isPresent()) {
                    classTeacher.setBaseTeacherId(optionalTeacher.get().getBaseTeacherId());
                    classTeacher.setIdentity(optionalTeacher.get().getIdentity());
                    classTeacher.setTeacherName(optionalTeacher.get().getTeacherName());
                    classTeacher.setImageUrl(optionalTeacher.get().getImageUrl());
                    switch (classTeacher.getHourType()) {
                        case 1:
                            classTeacher.setHourTypeName("讲授");
                            break;
                        case 2:
                            classTeacher.setHourTypeName("实验");
                            break;
                        case 3:
                            classTeacher.setHourTypeName("上机");
                            break;
                        case 4:
                            classTeacher.setHourTypeName("其他");
                            break;
                        default:
                            break;
                    }
                }
            }

            //获取选课条件
            List<CssTaskInfo> cssTaskInfos = cssTaskInfoService.lambdaQuery().eq(CssTaskInfo::getTaskId, taskId).eq(CssTaskInfo::getType, 2).list();
            if (CollUtil.isEmpty(cssTaskInfos)) {
                throw new BizException("请先完成选课条件设置");
            }
            CssTaskInfo cssTaskInfo = cssTaskInfos.get(0);
            //获取课程数据
            List<Course> courses = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
            //填充数据
            List<TeachingClass> removeClass = new ArrayList<>();
            for (TeachingClass teachingClass : teachingClasses) {
                List<TeachingClassTeacher> teachingClassTeachers = classTeachers.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .collect(Collectors.toList());
                teachingClass.setTeachingClassTeachers(teachingClassTeachers);
                List<Long> studentIds = classStudents.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .map(TeachingClassStudent::getStudentId)
                        .collect(Collectors.toList());
                teachingClass.setStudentIds(studentIds);
                teachingClass.setLimitClassNum(cssTaskInfo.getClassNum());
                Optional<Course> optional = courses.stream().filter(a -> a.getCourseId().equals(teachingClass.getCourseId())).findFirst();
                if (optional.isPresent()) {
                    Course course = optional.get();
                    teachingClass.setCourseType(course.getCourseType());
                    teachingClass.setCourseNature(course.getCourseNature());
                    //删除环节
                    if (course.getFlag() == 2) {
                        removeClass.add(teachingClass);
                    }
                }
            }
            teachingClasses.removeAll(removeClass);
            resultDto.setTotal((long) teachingClasses.size());
            resultDto.setPages((long) (teachingClasses.size() % pageSize == 0 ? teachingClasses.size() / pageSize : teachingClasses.size() / pageSize + 1));

            //分页
            teachingClasses = teachingClasses.stream()
                    .sorted(Comparator.comparing(TeachingClass::getTeachingClassId))
                    .skip((long) (currentPage - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
            resultDto.setCurrentPage(currentPage);
            resultDto.setPageSize(pageSize);
            resultDto.setList(teachingClasses);
        } else if (flag == 2) {
            //获取设置的选课课程
            List<CourseSelection> cssSelectCourseList = courseSelectionService.lambdaQuery().eq(CourseSelection::getTaskId, taskId).eq(CourseSelection::getRoundId, roundId).list();
            List<Long> courseIds = cssSelectCourseList.stream().map(CourseSelection::getCourseId).distinct().collect(Collectors.toList());
            //获取教学班
            List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery()
                    .in(TeachingClass::getCourseId, courseIds)
                    .eq(TeachingClass::getTaskId, taskId)
                    .eq(StringUtils.isNotBlank(baseCollegeId), TeachingClass::getBaseCollegeId, baseCollegeId)
                    .eq(ObjUtil.isNotNull(courseId), TeachingClass::getCourseId, courseId)
                    .like(StringUtils.isNotBlank(keyword), TeachingClass::getTeachingClassName, keyword)
                    .eq(TeachingClass::getIsOptional, 1)
                    .ne(TeachingClass::getTeachingClassType, 0)
                    .isNull(TeachingClass::getUniqueShiftSign)
                    .eq(TeachingClass::getStudentCampus, roundId.toString())//轮次对应的教学班，用于确定哪些教学班级属于该轮次
                    .list();
            List<Long> ids = teachingClasses.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            List<TeachingClassTeacher> classTeachers = new ArrayList<>();
            List<TeachingClassStudent> classStudents = new ArrayList<>();
            if (CollUtil.isNotEmpty(ids)) {
                //获取教学班教师
                classTeachers = teachingClassTeacherService.lambdaQuery().in(TeachingClassTeacher::getTeachingClassId, ids).list();
                //获取教学班学生
                classStudents = teachingClassStudentService.lambdaQuery().in(TeachingClassStudent::getTeachingClassId, ids).eq(TeachingClassStudent::getFlag, 1).list();
                if (round != null && round.getSelectType().equals(4)) {
                    Date currentTime = new Date();
                    if (currentTime.after(round.getBeginTime()) && currentTime.before(round.getEndTime()) && round.getIsEnable().equals(1)) {
                        List<TeachingClassStudent> redisList = this.getSelectDataByRedis(taskId, teachingClasses);
                        for (TeachingClassStudent redisClass : redisList) {
                            //因为redis之前轮次选课数据不进行删除，所以仅当数据库不存在时添加为返回值
                            boolean isExist = classStudents.stream().anyMatch(a -> a.getTeachingClassId().equals(redisClass.getTeachingClassId()) && a.getStudentId().equals(redisClass.getStudentId()));
                            if (!isExist) {
                                classStudents.add(redisClass);
                            }
                        }
                    } else {
                        studentService.saveRedisData(taskId, teachingClasses, "Self");
//                        if (round.getRound() == null || !round.getRound().equals(1)) {
//                            studentService.saveRedisData(taskId, teachingClasses, "Self");
//                            round.setRound(1);
//                            cssTaskRoundService.updateById(round);
//                        }
                    }
                }
            }

            for (TeachingClassTeacher classTeacher : classTeachers) {
                Optional<Teacher> optionalTeacher = teacherList.stream().filter(a -> a.getTeacherId().equals(classTeacher.getTeacherId())).findFirst();
                if (optionalTeacher.isPresent()) {
                    classTeacher.setBaseTeacherId(optionalTeacher.get().getBaseTeacherId());
                    classTeacher.setIdentity(optionalTeacher.get().getIdentity());
                    classTeacher.setTeacherName(optionalTeacher.get().getTeacherName());
                    classTeacher.setImageUrl(optionalTeacher.get().getImageUrl());
                    switch (classTeacher.getHourType()) {
                        case 1:
                            classTeacher.setHourTypeName("讲授");
                            break;
                        case 2:
                            classTeacher.setHourTypeName("实验");
                            break;
                        case 3:
                            classTeacher.setHourTypeName("上机");
                            break;
                        case 4:
                            classTeacher.setHourTypeName("其他");
                            break;
                        default:
                            break;
                    }
                }
            }

            //获取选课条件
            List<CssTaskInfo> cssTaskInfos = cssTaskInfoService.lambdaQuery().eq(CssTaskInfo::getTaskId, taskId).eq(CssTaskInfo::getType, 2).list();
            if (CollUtil.isEmpty(cssTaskInfos)) {
                throw new BizException("请先完成选课条件设置");
            }
            CssTaskInfo cssTaskInfo = cssTaskInfos.get(0);
            //获取课程数据
            List<Course> courses = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
            //填充数据
            List<TeachingClass> removeClass = new ArrayList<>();
            for (TeachingClass teachingClass : teachingClasses) {
                List<TeachingClassTeacher> teachingClassTeachers = classTeachers.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .collect(Collectors.toList());
                teachingClass.setTeachingClassTeachers(teachingClassTeachers);
                List<Long> studentIds = classStudents.stream()
                        .filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId()))
                        .map(TeachingClassStudent::getStudentId)
                        .collect(Collectors.toList());
                teachingClass.setStudentIds(studentIds);
                teachingClass.setLimitClassNum(cssTaskInfo.getClassNum());
                Optional<Course> optional = courses.stream().filter(a -> a.getCourseId().equals(teachingClass.getCourseId())).findFirst();
                if (optional.isPresent()) {
                    Course course = optional.get();
                    teachingClass.setCourseType(course.getCourseType());
                    teachingClass.setCourseNature(course.getCourseNature());
                    //删除环节
                    if (course.getFlag() == 2) {
                        removeClass.add(teachingClass);
                    }
                }
            }
            teachingClasses.removeAll(removeClass);
            resultDto.setTotal((long) teachingClasses.size());
            resultDto.setPages((long) (teachingClasses.size() % pageSize == 0 ? teachingClasses.size() / pageSize : teachingClasses.size() / pageSize + 1));

            //分页
            teachingClasses = teachingClasses.stream()
                    .sorted(Comparator.comparing(TeachingClass::getTeachingClassId))
                    .skip((long) (currentPage - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
            resultDto.setCurrentPage(currentPage);
            resultDto.setPageSize(pageSize);
            resultDto.setList(teachingClasses);

        }
        return resultDto;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addStudentRetakeTeachingClass(List<AddTeachingClassDto> list, Integer taskId, String baseCollegeId, String collegeName, String gradeId, String gradeName, Integer campusId, String campusName) {

        if (CollUtil.isEmpty(list)) {
            throw new BizException("传入数据不能为空");
        }

        TaskInfo taskInfo = taskInfoService.getById(taskId);
        List<AssessmentMethod> assessmentMethods = assessmentMethodService.lambdaQuery().eq(AssessmentMethod::getTaskId, taskId).list();

        AssessmentMethod assessmentMethod = assessmentMethods.stream().filter(p -> "考试".equals(p.getAssessmentName())).findFirst().orElse(null);
        if (ObjUtil.isNull(assessmentMethod)) {
            AssessmentMethod assessmentMethod1 = new AssessmentMethod();
            assessmentMethod1.setAssessmentName("考试");
            assessmentMethod1.setTaskId(taskId);
            assessmentMethod1.setFlag(1);
            assessmentMethod1.setSchoolId(taskInfo.getSchoolId());
            assessmentMethodService.save(assessmentMethod1);
        }


        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();

        List<AssessmentMethod> assessmentMethods1 = assessmentMethodService.lambdaQuery().eq(AssessmentMethod::getTaskId, taskId).list();

        List<TeachingClassStudent> teachingClassStudents = new ArrayList<>();

        List<TeachingClassTeacher> teachingClassTeacherList = new ArrayList<>();


        List<TeachingClassWeek> teachingClassWeekList = new ArrayList<>();

        List<Schedule> schedules = new ArrayList<>();

        list.forEach(o -> {
            TeachingClass teachingClass = new TeachingClass();
            teachingClass.setTaskId(taskId);
            teachingClass.setTeachingClassName(o.getTeachingClassName());

            Course course = courseList.stream().filter(p -> p.getCourseId().equals(p.getCourseId())).findFirst().orElse(null);
            if (ObjUtil.isNotNull(course)) {
                teachingClass.setCourseId(o.getCourseId());
                teachingClass.setCourseName(o.getCourseName());
                teachingClass.setMajorProp(course.getMajorProp());
                teachingClass.setStudyNature(course.getCourseNature());
            }
            teachingClass.setCollegeName(collegeName);
            teachingClass.setBaseCollegeId(baseCollegeId);
            teachingClass.setClassNum(o.getClassNum());
            teachingClass.setGradeId(gradeId);
            teachingClass.setGradeName(gradeName);
            teachingClass.setTeachingClassType(4);
            teachingClass.setFlag(1);
            teachingClass.setCampusId(campusId);
            teachingClass.setCampusName(campusName);
            teachingClass.setIsEnable(0);
            if (CollUtil.isNotEmpty(assessmentMethods1)) {
                AssessmentMethod assessmentMethod2 = assessmentMethods1.stream().filter(p -> "考试".equals(p.getAssessmentName())).findFirst().orElse(null);
                teachingClass.setAssessmentId(assessmentMethod2.getAssessmentId());
                teachingClass.setAssessmentName(assessmentMethod2.getAssessmentName());
            }
            teachingClassService.save(teachingClass);
            List<Long> studentIdList = o.getStudentIdList();

            studentIdList.forEach(s -> {
                TeachingClassStudent teachingClassStudent = new TeachingClassStudent();
                teachingClassStudent.setTeachingClassId(teachingClass.getTeachingClassId());
                teachingClassStudent.setCourseId(o.getCourseId());
                teachingClassStudent.setFlag(1);
                teachingClassStudent.setStudentId(s);
                teachingClassStudents.add(teachingClassStudent);

            });

            List<AddTeachingClassTeacherDto> teachingClassTeachers = o.getTeachingClassTeachers();
            teachingClassTeachers.forEach(t -> {
                Teacher teacher = teacherService.lambdaQuery().eq(Teacher::getBaseTeacherId, t.getBaseTeacherId()).eq(Teacher::getTaskId, taskId).one();
                if (ObjUtil.isNotNull(teacher)) {
                    TeachingClassTeacher teachingClassTeacher = new TeachingClassTeacher();
                    teachingClassTeacher.setTeachingClassId(teachingClass.getTeachingClassId());
                    teachingClassTeacher.setHourType(t.getHourType());
                    teachingClassTeacher.setTeacherId(teacher.getTeacherId());
                    teachingClassTeacherList.add(teachingClassTeacher);
                } else {
                    Teacher teacher1 = new Teacher();
                    teacher1.setBaseTeacherId(t.getBaseTeacherId());
                    teacher1.setTeacherName(t.getTeacherName());
                    teacher1.setTaskId(taskId);
                    teacher1.setImageUrl(t.getImageUrl());
                    teacher1.setIdentity(t.getIdentity());
                    teacher1.setIsCampusCross(1);
                    teacher1.setSchoolId(taskInfo.getSchoolId());
                    teacher1.setTerm(taskInfo.getTerm());
                    teacherService.save(teacher1);
                    TeachingClassTeacher teachingClassTeacher = new TeachingClassTeacher();
                    teachingClassTeacher.setTeachingClassId(teachingClass.getTeachingClassId());
                    teachingClassTeacher.setHourType(t.getHourType());
                    teachingClassTeacher.setTeacherId(teacher1.getTeacherId());
                    teachingClassTeacherList.add(teachingClassTeacher);

                }
            });


            List<AddTeachingClassWeekDto> teachingClassWeeks = o.getTeachingClassWeeks();

            teachingClassWeeks.forEach(tw -> {
                TeachingClassWeek teachingClassWeek = new TeachingClassWeek();
                teachingClassWeek.setTeachingClassId(teachingClass.getTeachingClassId());
                teachingClassWeek.setWeek(tw.getWeek());
                teachingClassWeek.setHourType(tw.getHourType());
                teachingClassWeek.setTotalHour(tw.getTotalHour());
                teachingClassWeek.setWeekNum(tw.getWeekNum());
                teachingClassWeek.setConnectSection(tw.getConnectSection());
                teachingClassWeek.setConnectNumber(tw.getConnectNumber());
                teachingClassWeek.setRoomType(tw.getRoomType());
                teachingClassWeek.setRoomTypeName(tw.getRoomTypeName());
                teachingClassWeekList.add(teachingClassWeek);

                List<AddTimeCode> timeCodes = tw.getTimeCodes();
                if (!CollUtil.isEmpty(timeCodes)) {
                    timeCodes.forEach(tc -> {
                        List<AddGroupDto> groupList = tc.getGroupList();
                        groupList.forEach(g -> {
                            Schedule schedule = new Schedule();
                            schedule.setTaskId(taskId);
                            schedule.setTeachingClassId(teachingClass.getTeachingClassId());
                            schedule.setTeachingClassName(teachingClass.getTeachingClassName());
                            schedule.setCourseId(teachingClass.getCourseId());
                            schedule.setCourseName(teachingClass.getCourseName());
                            schedule.setRoomId(g.getRoomId());
                            schedule.setTimeCode(g.getTimeCode());
                            schedule.setTimeGroup(g.getTimeGroup());
                            schedule.setPreGroup(g.getTimeGroup());
                            schedule.setHourType(g.getHourType());
                            schedule.setConnectSection(groupList.size());
                            schedule.setWeek(g.getWeek());
                            schedule.setFlag(0);
                            schedules.add(schedule);
                        });
                    });
                }
            });

        });

        //保存相关参数
        if (CollUtil.isNotEmpty(teachingClassStudents)) {
            teachingClassStudentService.saveOrUpdateBatch(teachingClassStudents);
        }

        List<TeachingClassTeacher> teachingClassTeacherList1 = teachingClassTeacherList.stream().distinct().collect(Collectors.toList());

        if (CollUtil.isNotEmpty(teachingClassTeacherList1)) {
            teachingClassTeacherService.saveOrUpdateBatch(teachingClassTeacherList1);
        }


        if (CollUtil.isNotEmpty(teachingClassWeekList)) {

            teachingClassWeekService.saveOrUpdateBatch(teachingClassWeekList);
        }

        if (CollUtil.isNotEmpty(schedules)) {

            scheduleService.saveOrUpdateBatch(schedules);
        }

        //删除临时表中的数据
        List<String> uuidList = list.stream().map(AddTeachingClassDto::getUuid).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(uuidList)) {
            scheduleSelectService.lambdaUpdate().eq(ScheduleSelect::getTaskId, taskId).in(ScheduleSelect::getTeachingClassId, uuidList).remove();
        }


        return "重修教学班顺利生成";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importSelfCourseTeachingClass(HttpServletResponse response, Integer taskId, Integer flag, String uuid, MultipartFile file) {
        boolean b = checkFile(file);
        if (!b) {
            throw new BizException("该文件不是excel文件");
        }

        List<ErrorExcelVo> errorExcelVos = new ArrayList<>();

        List<ExcelSelfTeachingDto> excel = this.readSelfTeachingClassToExcel(file);

        //导入该计划对应的教学班
        List<TeachingClass> teachingClasses = teachingClassMapper.selectList(new LambdaQueryWrapper<TeachingClass>()
                .eq(TeachingClass::getTaskId, taskId));

        WeekDateVo weekDateVo = taskInfoService.countWeek(taskId);

        Integer weekCount = Math.toIntExact(weekDateVo.getWeekCount());

        List<Student> students = studentService.lambdaQuery().eq(Student::getTaskId, taskId).list();

        Map<String, List<Student>> gradeMap = students.stream().collect(Collectors.groupingBy(Student::getGradeName));

        TaskInfo taskInfo = taskInfoService.getById(taskId);

//        List<BaseCourse> baseCourse = yunBasicService.getBaseCourse(taskInfo.getSchoolId());
//        Map<String, BaseCourse> courseMap = baseCourse.stream().collect(Collectors.toMap(BaseCourse::getCourseName, a -> a));

        Map<String, Course> courseMap = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list()
                .stream().collect(Collectors.toMap(Course::getCourseCode, course -> course));

        Map<String, String> collegeMap = collegeService.lambdaQuery().eq(College::getTaskId, taskId).list().stream().collect(Collectors.toMap(College::getCollegeName, College::getBaseCollegeId));

        List<Campus> campus = campusService.lambdaQuery().eq(Campus::getTaskId, taskId).list();
        Campus campus1 = new Campus();
        if (CollUtil.isNotEmpty(campus)) {
            campus1 = campus.get(0);
        }
        //获取教师信息
        Map<String, Teacher> teacherMap = teacherService.lambdaQuery().eq(Teacher::getSchoolId, taskInfo.getSchoolId())
                .eq(Teacher::getTerm, taskInfo.getTerm()).list()
                .stream().collect(Collectors.toMap(Teacher::getBaseTeacherId, Function.identity()));

        //待插入数据 教学班 教学班对应学生 教学班对应教师 教学班参数设置
        List<TeachingClass> teachingClassList = new ArrayList<>();
        List<TeachingClassTeacher> teachingClassTeacherList = new ArrayList<>();
        List<TeachingClassWeek> teachingClassWeekList = new ArrayList<>();

        List<Long> deleteTeachingClassIds = new ArrayList<>();

        //记录当前行数
        long index = 3;
        for (ExcelSelfTeachingDto excelTeachingClass : excel) {
            //存储当前行唯一标识
            excelTeachingClass.setIndex(index);
            index++;
        }

        Map<String, List<ExcelSelfTeachingDto>> courseTeachingClassMap = excel.stream().collect(Collectors.groupingBy(ExcelSelfTeachingDto::getTeachingClassName));

        Campus finalCampus = campus1;
        courseTeachingClassMap.forEach((key, value) -> {
            List<ErrorExcelVo> errorExcelVos1 = new ArrayList<>();
            value.forEach(v -> {
                if (!courseMap.containsKey(v.getCourseCode().trim())) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("课程没有在基础平台课程库开启" + v.getCourseName());
                    errorExcelVos1.add(errorExcelVo);
                }

                if (StrUtil.isNotBlank(v.getCollegeName()) && ObjUtil.isNull(collegeMap.get(v.getCollegeName()))) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg(v.getTeachingClassName() + "开课单位未设置");
                    errorExcelVos1.add(errorExcelVo);
                }

                if (!gradeMap.containsKey(v.getGradeName().trim())) {
                    ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                    errorExcelVo.setErrorIndex(v.getIndex());
                    errorExcelVo.setErrorMsg("年级未设置" + v.getGradeName());
                    errorExcelVos1.add(errorExcelVo);
                }

            });

            if (CollUtil.isNotEmpty(errorExcelVos1)) {
                errorExcelVos.addAll(errorExcelVos1);
            }

            if (CollUtil.isEmpty(errorExcelVos1)) {
                value.forEach(o -> {

                    List<TeachingClass> teachingClassList1 = teachingClasses.stream().filter(p -> p.getTeachingClassName().equals(o.getTeachingClassName())).collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(teachingClassList1)) {
                        List<Long> teachingClassIds = teachingClassList1.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
                        deleteTeachingClassIds.addAll(teachingClassIds);

                    }

                    teachingClassList.add(new TeachingClass().setTaskId(taskId)
                            .setTeachingClassId(o.getIndex())
                            .setTeachingClassName(o.getTeachingClassName())
                            .setCourseId(courseMap.get(o.getCourseCode().trim()).getCourseId())
                            .setCourseName(o.getCourseName())
                            .setBaseCollegeId(collegeMap.get(o.getCollegeName()))
                            .setStudyNature(courseMap.get(o.getCourseCode().trim()).getCourseNature())
                            .setMajorProp(courseMap.get(o.getCourseCode().trim()).getMajorProp())
                            .setCollegeName(o.getCollegeName())
                            .setGradeId(gradeMap.get(o.getGradeName()).get(0).getGradeId())
                            .setGradeName(o.getGradeName())
                            .setCampusId(finalCampus.getCampusId())
                            .setCampusName(finalCampus.getCampusName())
                            .setTeachingClassType(1)
                            .setFlag(1)
                            .setIsOptional(1)
                            .setClassNum(Integer.parseInt(o.getClassNum())));

                    //待插入教学班对应学生 该行政班学生及改学号学生
                    Course course = courseMap.get(o.getCourseCode().trim());
                    if (ObjUtil.isNull(course.getLectureHour())) {
                        TeachingClassWeek teachingClassWeek = new TeachingClassWeek();

                        teachingClassWeek.setTeachingClassId(o.getIndex());

                        teachingClassWeek.setHourType(1);
                        teachingClassWeek.setWeek("0");
                        teachingClassWeek.setWeekNum(1);
                        teachingClassWeek.setConnectNumber(1);
                        teachingClassWeek.setConnectSection(1);
                        teachingClassWeek.setTotalHour(0);
                        teachingClassWeekList.add(teachingClassWeek);

                    }

                    if (course.getLectureHour() != null) {
                        TeachingClassWeek teachingClassWeek = new TeachingClassWeek();
                        teachingClassWeek.setTeachingClassId(o.getIndex());

                        teachingClassWeek.setHourType(1);
                        teachingClassWeek.setWeek("0");
                        teachingClassWeek.setWeekNum((int) (course.getLectureHour() / weekCount) == 0 ? 1 : (int) (course.getLectureHour() / weekCount));
                        teachingClassWeek.setConnectNumber(1);
                        teachingClassWeek.setConnectSection(1);
                        teachingClassWeek.setTotalHour(course.getLectureHour());
                        teachingClassWeekList.add(teachingClassWeek);
                    }

                    if (org.apache.commons.lang3.StringUtils.isNotBlank(o.getBaseTeacherId())) {
                        TeachingClassTeacher teachingClassTeacher = new TeachingClassTeacher();
                        teachingClassTeacher.setTeachingClassId(o.getIndex());
                        teachingClassTeacher.setTeacherId(teacherMap.get(o.getBaseTeacherId().trim()).getTeacherId());
                        teachingClassTeacher.setHourType(1);
                        teachingClassTeacherList.add(teachingClassTeacher);
                    }
                });
            }
        });

        Integer size1 = errorExcelVos.size();

        if (CollUtil.isNotEmpty(errorExcelVos)) {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));

            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");

            MyExcelUtils.exportExcel(errorExcelVos,
                    "导入教学任务错误信息",
                    "错误信息",
                    ErrorExcelVo.class,
                    "导入教学任务错误信息" + time + ".xls", response);
        }

        //插入教学班
        if (size1.equals(0)) {
            List<TeachingClass> list = teachingClassService.lambdaQuery().orderByDesc(TeachingClass::getTeachingClassId).list();

            Long teachingClassId = 0L;

            if (CollUtil.isNotEmpty(list)) {
                TeachingClass teachingClass = list.get(0);
                teachingClassId = teachingClass.getTeachingClassId();
            }

            Long finalTeachingClassId = teachingClassId;
            teachingClassList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
                o.setStudentCampus(uuid);
            });

            teachingClassWeekList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            teachingClassTeacherList.forEach(o -> {
                o.setTeachingClassId(o.getTeachingClassId() + finalTeachingClassId);
            });

            if (flag.equals(2)) {
                List<Long> ids = teachingClassService.lambdaQuery().eq(TeachingClass::getStudentCampus, uuid).list()
                        .stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
                teachingClassService.deleteClass(ids);
                courseSelectionService.lambdaUpdate().eq(CourseSelection::getUuid, uuid).remove();
            }

            List<CourseSelection> courseSelectionList = new ArrayList<>();
            for (ExcelSelfTeachingDto excelSelfTeachingDto : excel) {
                CourseSelection view = new CourseSelection();
                view.setUuid(uuid);
                view.setTaskId(taskId);
                view.setBaseCollegeName(excelSelfTeachingDto.getCollegeName());
                view.setGradeName(excelSelfTeachingDto.getGradeName());
                view.setGradeId(gradeMap.get(excelSelfTeachingDto.getGradeName()).get(0).getGradeId());
                view.setBaseCollegeId(gradeMap.get(excelSelfTeachingDto.getGradeName()).get(0).getBaseCollegeId());
                view.setCourseName(excelSelfTeachingDto.getCourseName());
                view.setCourseId(courseMap.get(excelSelfTeachingDto.getCourseCode().trim()).getCourseId());
                courseSelectionList.add(view);
            }
            courseSelectionService.saveBatch(courseSelectionList);

            teachingClassService.saveBatch(teachingClassList);
            teachingClassWeekService.saveOrUpdateBatch(teachingClassWeekList);
            teachingClassTeacherService.saveOrUpdateBatch(teachingClassTeacherList);

            if (CollUtil.isNotEmpty(deleteTeachingClassIds)) {
                teachingClassService.lambdaUpdate().in(TeachingClass::getTeachingClassId, deleteTeachingClassIds).remove();
            }
        }
    }

    @Override
    public Boolean selectConflictCheck(Integer taskId, Long studentId, Long teachingClassId, String ids) {
        List<ScheduleRedisDto> allSchedules = getScheduleFromRedis(taskId);

        CssTaskInfo taskInfo = cssTaskInfoService.lambdaQuery()
                .eq(CssTaskInfo::getTaskId, taskId)
                .eq(CssTaskInfo::getType,2)
                .one();
        if (taskInfo == null || taskInfo.getCourseConflict() == 1) {
            return true;
        }

        List<ScheduleRedisDto> studentSchedule = allSchedules.stream()
                .filter(o -> o.getTeachingClassType() == 0
                        && StrUtil.isNotEmpty(o.getStudentIds())
                        && Arrays.stream(o.getStudentIds().split(","))
                        .anyMatch(s -> s.equals(String.valueOf(studentId)))
                )
                .collect(Collectors.toList());

        if (StrUtil.isNotEmpty(ids)){
            List<Long> selectIds = Arrays.stream(ids.split(","))
                    .map(Long::valueOf)
                    .collect(Collectors.toList());
            List<ScheduleRedisDto> collect = allSchedules.stream()
                    .filter(o -> selectIds.contains(o.getTeachingClassId()))
                    .collect(Collectors.toList());
            studentSchedule.addAll(collect);
        }

        List<ScheduleRedisDto> teachingClassSchedule = allSchedules.stream()
                .filter(o -> o.getTeachingClassId().equals(teachingClassId))
                .collect(Collectors.toList());


        if (CollUtil.isEmpty(teachingClassSchedule) || CollUtil.isEmpty(studentSchedule)) {
            return true;
        }

        for (ScheduleRedisDto current : teachingClassSchedule) {

            String currentTimeCode = current.getTimeCode();
            String currentWeek = current.getWeek();

            boolean b = studentSchedule.stream().anyMatch(schedule ->
                    StrUtil.isNotEmpty(schedule.getTimeCode())
                            && schedule.getTimeCode().equals(currentTimeCode)
                            && BinaryUtil.binaryAnd(schedule.getWeek(), currentWeek).contains("1"));
            if (b) {
                return false;
            }

        }

        return true;
    }

    @Override
    public List<ScheduleRedisDto> getStudentSchedule(Integer taskId, Long studentId) {
        List<ScheduleRedisDto> allSchedules = getScheduleFromRedis(taskId);
        List<ScheduleRedisDto> studentSchedule = allSchedules.stream()
                .filter(o -> o.getTeachingClassType() == 0
                        && StrUtil.isNotEmpty(o.getStudentIds())
                        && Arrays.stream(o.getStudentIds().split(","))
                        .anyMatch(s -> s.equals(String.valueOf(studentId)))
                ).peek(o -> o.setStudentIds(""))
                .collect(Collectors.toList());
        return studentSchedule;
    }

    private List<ScheduleRedisDto> getScheduleFromRedis(Integer taskId) {
        List<ScheduleRedisDto> allSchedules = new ArrayList<>();
        String key = GlobalConstant.REDIS_PREFIX + taskId + ":" + "schedules";
        String lockKey = key + "lock";
        if (!redisUtil.hasKey(key)) {
            RLock lock = redissonClient.getLock(lockKey);
            lock.lock(10, TimeUnit.MINUTES);
            try {
                if (!redisUtil.hasKey(key)) {
                    List<ScheduleRedisDto> scheduleRedisDtos = scheduleMapper.scheduleToRedis(taskId);
                    redisUtil.set(key, scheduleRedisDtos);
                    return scheduleRedisDtos;
                }
            } catch (Exception e) {
                throw new BizException("服务器异常，请联系管理员");
            } finally {
                lock.unlock();
            }
        }

        allSchedules = (List<ScheduleRedisDto>) redisUtil.get(key);
        return allSchedules;
    }

    private boolean checkFile(MultipartFile file) {

        String contentType = file.getContentType();
        String fileName = file.getOriginalFilename();

        // 检查文件扩展名是否为.xls或.xlsx
        boolean isExcel2003 = fileName.matches("^.+\\.(?i)(xls)$");
        boolean isExcel2007 = fileName.matches("^.+\\.(?i)(xlsx)$");

        // 检查Content-Type
        boolean isExcel = contentType.equals("application/vnd.ms-excel") || contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");


        return isExcel || isExcel2003 || isExcel2007;
    }

    private List<ExcelSelfTeachingDto> readSelfTeachingClassToExcel(MultipartFile file) {


        List<ExcelSelfTeachingDto> excelTeachingClassDtos = new ArrayList<>();

        List<String> expectedHeaders = Arrays.asList(
                "教学班名称", "课程名称", "课程代码", "所属开课单位", "年级", "选课容量", "上课教师工号", "上课教师");
        try {
            InputStream inputStream = file.getResource().getInputStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream, 0);
            //读取表头 判断是否符合预期
            List<String> actualHeaders = reader.readRow(1).stream()
                    .map(Object::toString).filter(org.apache.commons.lang3.StringUtils::isNotBlank).collect(Collectors.toList());
            if (!expectedHeaders.equals(actualHeaders)) {
                throw new BizException(5, "导入模板不匹配，请按照标准模板编辑后导入");
            }

            reader.addHeaderAlias("教学班名称", "teachingClassName");
            reader.addHeaderAlias("课程名称", "courseName");
            reader.addHeaderAlias("课程代码", "courseCode");
            reader.addHeaderAlias("所属开课单位", "collegeName");
            reader.addHeaderAlias("年级", "gradeName");
            reader.addHeaderAlias("选课容量", "classNum");
            reader.addHeaderAlias("上课教师", "teacherName");
            reader.addHeaderAlias("上课教师工号", "baseTeacherId");

            excelTeachingClassDtos = reader.read(1, 2, ExcelSelfTeachingDto.class);
            reader.close();
        } catch (IOException e) {
            log.info("excel导入教学任务失败:{}", e.getMessage());
        }
        if (excelTeachingClassDtos.size() == 0) {
            throw new BizException(5, "导入数据为空，请检查后重新导入");
        }
        return excelTeachingClassDtos;
    }


    public List<TeachingClassWeek> initTeachingClassWeek(List<TeachingClass> teachingClassList) {
        //待新增教学班参数
        List<TeachingClassWeek> allTeachingClassWeeks = new ArrayList<>();

        //获取该课程对应课程参数
        List<Long> courseIds = teachingClassList.stream().map(TeachingClass::getCourseId).collect(Collectors.toList());
        Map<Long, List<CourseWeek>> courseWeekMap = courseWeekService.lambdaQuery().in(CourseWeek::getCourseId, courseIds).list()
                .stream().collect(Collectors.groupingBy(CourseWeek::getCourseId));
        //遍历教学班 生成教学班参数
        for (TeachingClass teachingClass : teachingClassList) {
            List<CourseWeek> courseWeeks = courseWeekMap.get(teachingClass.getCourseId());
            //遍历每个授课类型的课程参数生成教学班参数  教学班参数前端没传的话就由课程参数替代
            if (CollUtil.isNotEmpty(courseWeeks)) {
                courseWeeks.forEach(courseWeek -> {
                    TeachingClassWeek teachingClassWeek = new TeachingClassWeek();
                    //遍历前端传的教学班参数
                    Optional<TeachingClassWeek> front = teachingClass.getTeachingClassWeeks().stream()
                            .filter(a -> a.getHourType().equals(courseWeek.getHourType())).findFirst();
                    if (front.isPresent()) {
                        //存在的话就用前端传的
                        BeanUtil.copyProperties(front.get(), teachingClassWeek);
                        teachingClassWeek.setTeachingClassId(teachingClass.getTeachingClassId());
                    } else {
                        BeanUtil.copyProperties(courseWeek, teachingClassWeek);
                        teachingClassWeek.setTeachingClassId(teachingClass.getTeachingClassId());
                    }
                    allTeachingClassWeeks.add(teachingClassWeek);
                });
            }
        }
        for (TeachingClassWeek week : allTeachingClassWeeks) {
            WeekDateVo dateVo = taskInfoService.countWeek(teachingClassList.get(0).getTaskId());
            if (StrUtil.isEmpty(week.getWeek())) {
                StringBuilder str = new StringBuilder();
                for (long i = 0; i < dateVo.getWeekCount(); i++) {
                    str.append("1");
                }
                week.setWeek(str.toString());
            }
        }
        return allTeachingClassWeeks;
    }


    @Override
    public List<Student> getStudentListConfirmSelectionResults(Integer taskId, Long courseId, Integer flag) {

        List<Student> students = new ArrayList<>();
        List<Student> studentList = studentService.lambdaQuery().eq(Student::getTaskId, taskId).list();

        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).eq(Course::getCourseId, courseId).list();
        //重修相关逻辑
        if (flag == 1) {
            List<StudentRetake> list = studentRetakeService.lambdaQuery().eq(StudentRetake::getTaskId, taskId).list();
            if (CollUtil.isNotEmpty(list)) {
                Course course = courseList.stream().filter(p -> p.getCourseId().equals(courseId)).findFirst().orElse(null);
                if (ObjUtil.isNotNull(course)) {
                    List<String> allBaseStudentIds = list.stream().filter(p -> p.getBaseCourseId().equals(course.getBaseCourseId())).map(StudentRetake::getBaseStudentId).collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(allBaseStudentIds)) {
                        List<Long> allStudentIds = studentList.stream().filter(p -> allBaseStudentIds.contains(p.getBaseStudentId())).map(Student::getStudentId).collect(Collectors.toList());

                        List<Long> teachingClassIds = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).eq(TeachingClass::getTeachingClassType, 4).list().stream()
                                .map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(teachingClassIds)) {
                            List<TeachingClassStudent> teachingClassStudents = teachingClassStudentService.lambdaQuery().in(TeachingClassStudent::getTeachingClassId, teachingClassIds).eq(TeachingClassStudent::getFlag, 1).list();

                            List<Long> studentId = teachingClassStudents.stream().map(TeachingClassStudent::getStudentId).collect(Collectors.toList());

                            allStudentIds = allStudentIds.stream().filter(p -> !studentId.contains(p)).collect(Collectors.toList());

                            if (CollUtil.isNotEmpty(allStudentIds)) {
                                List<Long> finalAllStudentIds = allStudentIds;
                                List<Student> studentList1 = studentList.stream().filter(p -> finalAllStudentIds.contains(p.getStudentId())).collect(Collectors.toList());
                                if (CollUtil.isNotEmpty(studentList1)) {
                                    students.addAll(studentList1);
                                }

                            }


                        } else {

                            List<Student> studentList1 = studentList.stream().filter(p -> allBaseStudentIds.contains(p.getBaseStudentId())).collect(Collectors.toList());

                            if (CollUtil.isNotEmpty(studentList1)) {
                                students.addAll(studentList1);
                            }
                        }


                    }


                }


            }


        } else if (flag == 2) {
            //获取全部已选学生
            //获取该课程下的所有教学班
            List<TeachingClass> teachingClasses = teachingClassService.lambdaQuery()
                    .eq(TeachingClass::getCourseId, courseId)
                    .eq(TeachingClass::getTaskId, taskId).list();
            List<Long> teachingClassIds = teachingClasses.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
            //获取该课程下所有教学班中的学生-全部已选学生
            List<Student> selectStudents = new ArrayList<>();
            if (CollUtil.isNotEmpty(teachingClassIds)) {
                List<TeachingClassStudent> classStudents = teachingClassStudentService.lambdaQuery()
                        .in(TeachingClassStudent::getTeachingClassId, teachingClassIds)
                        .eq(TeachingClassStudent::getFlag, 1).list();
                List<Long> studentIds = classStudents.stream().map(TeachingClassStudent::getStudentId).collect(Collectors.toList());
                selectStudents = studentService.lambdaQuery().in(Student::getStudentId, studentIds).list();
            }
            //获取全部应选学生
            Course course = courseService.getById(courseId);
            List<PlanTeachingCourse> planTeachingCourses = planTeachingCourseService.lambdaQuery()
                    .eq(PlanTeachingCourse::getBaseCourseId, course.getBaseCourseId()).list();
            List<String> planTeachingIds = planTeachingCourses.stream().map(PlanTeachingCourse::getBaseTeachingPlanId).collect(Collectors.toList());
            if (CollUtil.isEmpty(planTeachingIds)) {
                throw new BizException("此课程在本学期没有学生需要上");
            }
            List<PlanTeachingStudent> planTeachingStudents = planTeachingStudentService.lambdaQuery()
                    .in(PlanTeachingStudent::getBaseTeachingPlanId, planTeachingIds).list();
            List<String> studentNeedIds = planTeachingStudents.stream().map(PlanTeachingStudent::getBaseStudentId).collect(Collectors.toList());
            List<Student> needStudents = studentService.lambdaQuery()
                    .in(Student::getBaseStudentId, studentNeedIds).list();
            needStudents.removeAll(selectStudents);
            students.addAll(needStudents);
        }
        return students;
    }

    public List<CssPreSelectStudent> getPreDataByRedis(Integer taskId) {
        String redisKey = studentServiceImpl.getCacheKeys(taskId, null, 8, null);
        Map<Object, Object> hmget = redisUtil.hmget(redisKey);
        Collection<Object> values = hmget.values();
        List<CssPreSelectStudent> redisList = new ArrayList<>();
        for (Object value : values) {
            CssPreSelectStudent model = (CssPreSelectStudent) value;
            model.setTaskId(taskId);
            //日志需要输出选课数据和退选数据，所以去除了退选的过滤条件
            //选课结束，保存选课数据时再做过滤
            redisList.add(model);
//            if (model.getFlag().equals(1)) {
//                redisList.add(model);
//            }
        }
        return redisList;
    }

    public List<TeachingClassStudent> getSelectDataByRedis(Integer taskId, List<TeachingClass> teachingClasses) {
        //redis暂存的学生选课数据
        List<Long> ids = teachingClasses.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        String redisKey = studentServiceImpl.getCacheKeys(taskId, null, 3, null);
        Map<Object, Object> hmget = redisUtil.hmget(redisKey);
        Collection<Object> values = hmget.values();
        List<TeachingClassStudent> redisList = new ArrayList<>();
        for (Object value : values) {
            TeachingClassStudent model = (TeachingClassStudent) value;
            if (model.getFlag().equals(1)) {
                redisList.add(model);
            }
        }
        redisList = redisList.stream().filter(a -> ids.contains(a.getTeachingClassId())).collect(Collectors.toList());
        for (TeachingClassStudent item : redisList) {
            item.setCourseId(teachingClasses.stream().filter(o -> o.getTeachingClassId().equals(item.getTeachingClassId())).findFirst().get().getCourseId());
        }
        return redisList;
    }
}
